Implement clean URLs feature (Issue #89)
When `clean-urls?` is set in config, emit pages as subdirectories `prefix/root/page-name/index.html` instead of `prefix/root/page-name.html`. Links in emitted HTML then point to `prefix/root/page-name/`. When `clean-urls?` not set, behaves as before. Refactor most URI generation into a new `page-uri` function. `page-uri` replaces most calls* to `path`, all calls to `post-uri` and all calls to the old `page-uri`. Introduce function `create-file-recursive`. Function creates file parent if not exists. Introduce function `write-html`. When `clean-urls?` is set, spits emitted HTML into subdirectories as described above; otherwise behaves like `create-file`. Replaces most* calls to `create-file` Calls `create-file` or `create-file-recursive`. * Exceptions made for sitemap XML and RSS feed XML pages
This commit is contained in:
parent
b3bdba2804
commit
c18c3d60f2
2 changed files with 104 additions and 83 deletions
|
@ -11,7 +11,7 @@
|
|||
[cryogen-core.sass :as sass]
|
||||
[cryogen-core.markup :as m]
|
||||
[cryogen-core.io :refer
|
||||
[get-resource find-assets create-folder create-file wipe-public-folder
|
||||
[get-resource find-assets create-folder create-file-recursive create-file wipe-public-folder
|
||||
copy-resources copy-resources-from-theme path]]
|
||||
[cryogen-core.sitemap :as sitemap]
|
||||
[cryogen-core.rss :as rss])
|
||||
|
@ -47,15 +47,14 @@
|
|||
(let [fmt (java.text.SimpleDateFormat. date-fmt)]
|
||||
(.parse fmt (.substring file-name 0 10))))
|
||||
|
||||
(defn post-uri
|
||||
"Creates a post uri from the post file name"
|
||||
[file-name {:keys [blog-prefix post-root-uri]} mu]
|
||||
(path "/" blog-prefix post-root-uri (s/replace file-name (re-pattern-from-ext (m/ext mu)) ".html")))
|
||||
|
||||
(defn page-uri
|
||||
"Creates a page uri from the page file name"
|
||||
[page-name {:keys [blog-prefix page-root-uri]} mu]
|
||||
(path "/" blog-prefix page-root-uri (s/replace page-name (re-pattern-from-ext (m/ext mu)) ".html")))
|
||||
"Creates a URI from file name. `uri-type` is any of the uri types specified in config, e.g., `:post-root-uri`."
|
||||
([file-name params]
|
||||
(page-uri file-name nil params))
|
||||
([file-name uri-type {:keys [blog-prefix clean-urls?] :as params}]
|
||||
(let [page-uri (params uri-type)
|
||||
uri-end (if clean-urls? (s/replace file-name #"(index)?\.html" "/") file-name)]
|
||||
(path "/" blog-prefix page-uri uri-end))))
|
||||
|
||||
(defn read-page-meta
|
||||
"Returns the clojure map from the top of a markdown page/post"
|
||||
|
@ -94,7 +93,7 @@
|
|||
(let [{:keys [file-name page-meta content]} (page-content page config markup)]
|
||||
(merge
|
||||
(merge-meta-and-content file-name page-meta content)
|
||||
{:uri (page-uri file-name config markup)
|
||||
{:uri (page-uri file-name :page-root-uri config)
|
||||
:page-index (:page-index page-meta)})))
|
||||
|
||||
(defn parse-post
|
||||
|
@ -111,7 +110,7 @@
|
|||
{:date date
|
||||
:formatted-archive-group formatted-group
|
||||
:parsed-archive-group (.parse archive-fmt formatted-group)
|
||||
:uri (post-uri file-name config markup)
|
||||
:uri (page-uri file-name :post-root-uri config)
|
||||
:tags (set (:tags page-meta))}))))
|
||||
|
||||
(defn read-posts
|
||||
|
@ -178,9 +177,9 @@
|
|||
|
||||
(defn tag-info
|
||||
"Returns a map containing the name and uri of the specified tag"
|
||||
[{:keys [blog-prefix tag-root-uri]} tag]
|
||||
[config tag]
|
||||
{:name (name tag)
|
||||
:uri (path "/" blog-prefix tag-root-uri (str (name tag) ".html"))})
|
||||
:uri (page-uri (str (name tag) ".html") :tag-root-uri config)})
|
||||
|
||||
(defn add-prev-next
|
||||
"Adds a :prev and :next key to the page/post data containing the title and uri of the prev/next
|
||||
|
@ -199,6 +198,13 @@
|
|||
sidebar-pages false} (group-by #(boolean (:navbar? %)) pages)]
|
||||
(map (partial sort-by :page-index) [navbar-pages sidebar-pages])))
|
||||
|
||||
(defn write-html
|
||||
"When `clean-urls?` is set, appends `/index.html` before spit; otherwise just spits."
|
||||
[file-uri {:keys [clean-urls?]} data]
|
||||
(if clean-urls?
|
||||
(create-file-recursive (path file-uri "index.html") data)
|
||||
(create-file file-uri data)))
|
||||
|
||||
(defn compile-pages
|
||||
"Compiles all the pages into html and spits them out into the public folder"
|
||||
[{:keys [blog-prefix page-root-uri] :as params} pages]
|
||||
|
@ -207,13 +213,14 @@
|
|||
(create-folder (path "/" blog-prefix page-root-uri))
|
||||
(doseq [{:keys [uri] :as page} pages]
|
||||
(println "\t-->" (cyan uri))
|
||||
(create-file uri
|
||||
(render-file (str "/html/" (:layout page))
|
||||
(merge params
|
||||
{:active-page "pages"
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:page page
|
||||
:uri uri}))))))
|
||||
(write-html uri
|
||||
params
|
||||
(render-file (str "/html/" (:layout page))
|
||||
(merge params
|
||||
{:active-page "pages"
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:page page
|
||||
:uri uri}))))))
|
||||
|
||||
(defn compile-posts
|
||||
"Compiles all the posts into html and spits them out into the public folder"
|
||||
|
@ -223,14 +230,15 @@
|
|||
(create-folder (path "/" blog-prefix post-root-uri))
|
||||
(doseq [post posts]
|
||||
(println "\t-->" (cyan (:uri post)))
|
||||
(create-file (:uri post)
|
||||
(render-file (str "/html/" (:layout post))
|
||||
(merge params
|
||||
{:active-page "posts"
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:post post
|
||||
:disqus-shortname disqus-shortname
|
||||
:uri (:uri post)}))))))
|
||||
(write-html (:uri post)
|
||||
params
|
||||
(render-file (str "/html/" (:layout post))
|
||||
(merge params
|
||||
{:active-page "posts"
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:post post
|
||||
:disqus-shortname disqus-shortname
|
||||
:uri (:uri post)}))))))
|
||||
|
||||
(defn compile-tags
|
||||
"Compiles all the tag pages into html and spits them out into the public folder"
|
||||
|
@ -241,22 +249,25 @@
|
|||
(doseq [[tag posts] posts-by-tag]
|
||||
(let [{:keys [name uri]} (tag-info params tag)]
|
||||
(println "\t-->" (cyan uri))
|
||||
(create-file uri
|
||||
(render-file "/html/tag.html"
|
||||
(merge params
|
||||
{:active-page "tags"
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:name name
|
||||
:posts posts
|
||||
:uri uri})))))))
|
||||
(write-html uri
|
||||
params
|
||||
(render-file "/html/tag.html"
|
||||
(merge params
|
||||
{:active-page "tags"
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:name name
|
||||
:posts posts
|
||||
:uri uri})))))))
|
||||
|
||||
(defn compile-tags-page [{:keys [blog-prefix] :as params}]
|
||||
(println (blue "compiling tags page"))
|
||||
(create-file (path "/" blog-prefix "tags.html")
|
||||
(render-file "/html/tags.html"
|
||||
(merge params
|
||||
{:active-page "tags"
|
||||
:uri (path "/" blog-prefix "tags.html")}))))
|
||||
(let [uri (page-uri "tags.html" params)]
|
||||
(write-html uri
|
||||
params
|
||||
(render-file "/html/tags.html"
|
||||
(merge params
|
||||
{:active-page "tags"
|
||||
:uri uri})))))
|
||||
|
||||
(defn content-until-more-marker
|
||||
[^String content]
|
||||
|
@ -288,11 +299,11 @@
|
|||
(defn create-preview-links
|
||||
"Turn each vector of previews into a map with :prev and :next keys that contain the uri of the
|
||||
prev/next preview page"
|
||||
[previews blog-prefix]
|
||||
[previews params]
|
||||
(mapv (fn [[prev target next]]
|
||||
(merge target
|
||||
{:prev (if prev (path "/" blog-prefix "p" (str (:index prev) ".html")) nil)
|
||||
:next (if next (path "/" blog-prefix "p" (str (:index next) ".html")) nil)}))
|
||||
{:prev (if prev (page-uri (path "p" (str (:index prev) ".html")) params) nil)
|
||||
:next (if next (page-uri (path "p" (str (:index next) ".html")) params) nil)}))
|
||||
(partition 3 1 (flatten [nil previews nil]))))
|
||||
|
||||
(defn compile-preview-pages
|
||||
|
@ -300,45 +311,50 @@
|
|||
[{:keys [blog-prefix posts-per-page blocks-per-preview] :as params} posts]
|
||||
(when-not (empty? posts)
|
||||
(let [previews (-> (create-previews posts-per-page blocks-per-preview posts)
|
||||
(create-preview-links blog-prefix))
|
||||
previews (if (> (count previews) 1) (assoc-in previews [1 :prev] (path "/" blog-prefix "index.html")) previews)]
|
||||
(create-preview-links params))
|
||||
previews (if (> (count previews) 1) (assoc-in previews [1 :prev] (page-uri "index.html" params)) previews)]
|
||||
(create-folder (path "/" blog-prefix "p"))
|
||||
(doseq [{:keys [index posts prev next]} previews
|
||||
:let [index-page? (= 1 index)]]
|
||||
(create-file (if index-page? (path "/" blog-prefix "index.html") (path "/" blog-prefix "p" (str index ".html")))
|
||||
(render-file "/html/previews.html"
|
||||
(merge params
|
||||
{:active-page "preview"
|
||||
:home (when index-page? true)
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:posts posts
|
||||
:prev-uri prev
|
||||
:next-uri next})))))))
|
||||
(write-html (if index-page? (page-uri "index.html" params) (page-uri (path "p" (str index ".html")) params))
|
||||
params
|
||||
(render-file "/html/previews.html"
|
||||
(merge params
|
||||
{:active-page "preview"
|
||||
:home (when index-page? true)
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:posts posts
|
||||
:prev-uri prev
|
||||
:next-uri next})))))))
|
||||
|
||||
(defn compile-index
|
||||
"Compiles the index page into html and spits it out into the public folder"
|
||||
[{:keys [blog-prefix disqus?] :as params}]
|
||||
(println (blue "compiling index"))
|
||||
(create-file (path "/" blog-prefix "index.html")
|
||||
(render-file "/html/home.html"
|
||||
(merge params
|
||||
{:active-page "home"
|
||||
:home true
|
||||
:disqus? disqus?
|
||||
:post (get-in params [:latest-posts 0])
|
||||
:uri (path "/" blog-prefix "index.html")}))))
|
||||
(let [uri (page-uri "index.html" params)]
|
||||
(write-html uri
|
||||
params
|
||||
(render-file "/html/home.html"
|
||||
(merge params
|
||||
{:active-page "home"
|
||||
:home true
|
||||
:disqus? disqus?
|
||||
:post (get-in params [:latest-posts 0])
|
||||
:uri uri})))))
|
||||
|
||||
(defn compile-archives
|
||||
"Compiles the archives page into html and spits it out into the public folder"
|
||||
[{:keys [blog-prefix] :as params} posts]
|
||||
(println (blue "compiling archives"))
|
||||
(create-file (path "/" blog-prefix "archives.html")
|
||||
(render-file "/html/archives.html"
|
||||
(merge params
|
||||
{:active-page "archives"
|
||||
:archives true
|
||||
:groups (group-for-archive posts)
|
||||
:uri (path "/" blog-prefix "/archives.html")}))))
|
||||
(let [uri (page-uri "archives.html" params)]
|
||||
(write-html uri
|
||||
params
|
||||
(render-file "/html/archives.html"
|
||||
(merge params
|
||||
{:active-page "archives"
|
||||
:archives true
|
||||
:groups (group-for-archive posts)
|
||||
:uri uri})))))
|
||||
|
||||
(defn compile-authors
|
||||
"For each author, creates a page with filtered posts."
|
||||
|
@ -347,15 +363,16 @@
|
|||
(create-folder (path "/" blog-prefix author-root-uri))
|
||||
;; if the post author is empty defaults to config's :author
|
||||
(doseq [{:keys [author posts]} (group-for-author posts author)]
|
||||
(let [uri (path "/" blog-prefix author-root-uri (str author ".html"))]
|
||||
(let [uri (page-uri (str author ".html") :author-root-uri params)]
|
||||
(println "\t-->" (cyan uri))
|
||||
(create-file uri
|
||||
(render-file "/html/author.html"
|
||||
(merge params
|
||||
{:author author
|
||||
:groups (group-for-archive posts)
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:uri uri}))))))
|
||||
(write-html uri
|
||||
params
|
||||
(render-file "/html/author.html"
|
||||
(merge params
|
||||
{:author author
|
||||
:groups (group-for-archive posts)
|
||||
:servlet-context (path "/" blog-prefix "/")
|
||||
:uri uri}))))))
|
||||
|
||||
(defn tag-posts
|
||||
"Converts the tags in each post into links"
|
||||
|
@ -414,9 +431,9 @@
|
|||
:latest-posts (->> posts (take recent-posts) vec)
|
||||
:navbar-pages navbar-pages
|
||||
:sidebar-pages sidebar-pages
|
||||
:archives-uri (path "/" blog-prefix "archives.html")
|
||||
:index-uri (path "/" blog-prefix "index.html")
|
||||
:tags-uri (path "/" blog-prefix "tags.html")
|
||||
:archives-uri (page-uri "archives.html" config)
|
||||
:index-uri (page-uri "index.html" config)
|
||||
:tags-uri (page-uri "tags.html" config)
|
||||
:rss-uri (path "/" blog-prefix rss-name)
|
||||
:site-url (if (.endsWith site-url "/") (.substring site-url 0 (dec (count site-url))) site-url)
|
||||
:theme-path (str "file:resources/templates/themes/" (:theme config))})]
|
||||
|
|
|
@ -45,12 +45,16 @@
|
|||
[]))
|
||||
|
||||
(defn create-folder [folder]
|
||||
(let [loc (io/file (str public folder))]
|
||||
(let [loc (io/file (path public folder))]
|
||||
(when-not (.exists loc)
|
||||
(.mkdirs loc))))
|
||||
|
||||
(defn create-file [file data]
|
||||
(spit (str public file) data))
|
||||
(spit (path public file) data))
|
||||
|
||||
(defn create-file-recursive [file data]
|
||||
(create-folder (.getParent (io/file file)))
|
||||
(create-file file data))
|
||||
|
||||
(defn wipe-public-folder [keep-files]
|
||||
(let [filenamefilter (reify java.io.FilenameFilter (accept [this _ filename] (not (some #{filename} keep-files))))]
|
||||
|
|
Loading…
Reference in a new issue