Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
0d1451b
Add logging for case when `assortment` doesn't find anything to render
bhagany Dec 5, 2016
e70f76a
Add `assortment` task, for collections of collections
bhagany Dec 5, 2016
1e73150
Merge branch 'content-pipeline' into assortment
bhagany Dec 5, 2016
af4e9c6
Merge branch 'content-pipeline' into assortment
bhagany Dec 5, 2016
7e5ead4
Merge branch 'content-pipeline' into assortment
bhagany Dec 5, 2016
136eb68
Pedantic indentation fix
bhagany Dec 5, 2016
39b3b38
Merge branch 'content-pipeline' into assortment
bhagany Dec 5, 2016
0fa0554
Merge branch 'content-pipeline' into assortment
bhagany Dec 6, 2016
24b623b
merge content-pipeline -> assortment
bhagany Dec 11, 2016
d968a95
merge content-pipeline -> assortment
bhagany Dec 12, 2016
26280c8
merge content-pipeline -> assortment
bhagany Dec 18, 2016
71ffae5
Abstract assortment to make adding specialized assortments easier
bhagany Jan 6, 2017
e27d02b
Fix #63 - Add paginate task
bhagany Jan 6, 2017
460f8e8
Merge branch 'content-pipeline' into assortment
bhagany Jan 8, 2017
abff1fa
merge fileset-invictus -> assortment
bhagany Jan 10, 2017
97d8014
merge assortment -> assortify
bhagany Jan 10, 2017
2449f53
Merge branch 'assortify' into paginate
bhagany Jan 10, 2017
3e82e92
bring paginate up-to-date with fileset-invictus
bhagany Jan 10, 2017
0ebaca3
merge fileset-invictus -> assortment
bhagany Jan 11, 2017
cf277d2
merge assortment -> assortify
bhagany Jan 11, 2017
dfe3fc4
Merge branch 'assortify' into paginate
bhagany Jan 11, 2017
d8545c4
merge fileset-invictus -> assortify
bhagany Jan 17, 2017
c59e29c
Rename `assortment-impl` to `assortment-pre-wrap`
bhagany Jan 17, 2017
bb4377f
Merge branch 'assortify' into paginate
bhagany Jan 17, 2017
9ebaafe
Fix paginate implementation
bhagany Jan 17, 2017
70fd19b
Add `assortment-pre-wrap` docstring
bhagany Jan 17, 2017
2b0811d
Merge branch 'assortify' into paginate
bhagany Jan 17, 2017
6828c00
Rename `:group-meta` to `:entry`, because that's what it is
bhagany Jan 17, 2017
78ef0a0
Merge branch 'assortify' into paginate
bhagany Jan 17, 2017
6aab719
Remove redundant logging message
bhagany Jan 17, 2017
1ca2958
Remove `assortment` options from a previous implementation
bhagany Jan 18, 2017
bc7f8b0
Small cleanups
bhagany Jan 19, 2017
306ef3e
Test `assortment` and `collection`
bhagany Jan 19, 2017
fb24583
merge fileset-invictus -> assortify
bhagany Jan 19, 2017
04fcd64
Merge branch 'assortify' into paginate
bhagany Jan 19, 2017
9e82222
Name test correctly
bhagany Jan 19, 2017
a147487
Merge branch 'assortify' into paginate
bhagany Jan 19, 2017
596c913
Add `paginate` tests
bhagany Jan 19, 2017
0f2914e
Fix assortment tests
bhagany Jan 19, 2017
4e77fdf
typo
bhagany Jan 19, 2017
d2ff7c8
More paginate tests
bhagany Jan 19, 2017
83e3822
Add messages to checks
bhagany Jan 20, 2017
496d6df
Merge branch 'fileset-invictus' into assortify
bhagany Jan 20, 2017
d773c51
Merge branch 'fileset-invictus' into paginate
bhagany Jan 21, 2017
abee445
Add messages to checks
bhagany Jan 21, 2017
a5d7f3b
Merge branch 'fileset-invictus' into paginate
bhagany Jan 22, 2017
c844b27
Compose multiple checks in a single `testing` form
bhagany Jan 22, 2017
8541972
Merge branch 'fileset-invictus' into paginate
bhagany Jan 22, 2017
51408ff
Merge branch 'master' into paginate
bhagany Jan 22, 2017
0047919
Merge branch 'master' into paginate
bhagany Jan 23, 2017
9ca9893
Add page number to paginate metadata
bhagany Jan 24, 2017
24b40a4
Add `paginate` to example blog
bhagany Jan 24, 2017
ce9722c
Add missing source file
bhagany Jan 24, 2017
c13ca39
Merge branch 'master' into assortify
bhagany Jan 24, 2017
831e712
Add `assortment` to example blog
bhagany Jan 24, 2017
3f4004c
merge assortify -> paginate
bhagany Jan 24, 2017
750e25c
merge master -> paginate
bhagany Jan 25, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion examples/blog/build.boot
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
[hiccup "1.0.5"]
[pandeiro/boot-http "0.6.3-SNAPSHOT"]])

(require '[io.perun :refer :all]
(require '[clojure.string :as str]
'[io.perun :refer :all]
'[io.perun.example.index :as index-view]
'[io.perun.example.post :as post-view]
'[pandeiro.boot-http :refer [serve]])
Expand All @@ -26,6 +27,20 @@
(gravatar :source-key :author-email :target-key :author-gravatar)
(render :renderer 'io.perun.example.post/render)
(collection :renderer 'io.perun.example.index/render :page "index.html")
(paginate :renderer 'io.perun.example.paginate/render)
(assortment :renderer 'io.perun.example.assortment/render
:grouper (fn [entries]
(->> entries
(mapcat (fn [entry]
(if-let [kws (:keywords entry)]
(map #(-> [% entry]) (str/split kws #"\s*,\s*"))
[])))
(reduce (fn [result [kw entry]]
(let [path (str kw ".html")]
(-> result
(update-in [path :entries] conj entry)
(assoc-in [path :entry :keyword] kw))))
{}))))
(static :renderer 'io.perun.example.about/render :page "about.html")
(inject-scripts :scripts #{"start.js"})
(sitemap)
Expand Down
15 changes: 15 additions & 0 deletions examples/blog/src/io/perun/example/assortment.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(ns io.perun.example.assortment
(:require [hiccup.page :refer [html5]]))

(defn render [{global-meta :meta posts :entries entry :entry}]
(html5 {:lang "en" :itemtype "http://schema.org/Blog"}
[:head
[:title (str (:site-title global-meta) "|" (:keyword entry))]
[:meta {:charset "utf-8"}]
[:meta {:http-equiv "X-UA-Compatible" :content "IE=edge,chrome=1"}]
[:meta {:name "viewport" :content "width=device-width, initial-scale=1.0, user-scalable=no"}]]
[:body
[:h1 (str "Page " (:page entry))]
[:ul.items.columns.small-12
(for [post posts]
[:li (:title post)])]]))
15 changes: 15 additions & 0 deletions examples/blog/src/io/perun/example/paginate.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(ns io.perun.example.paginate
(:require [hiccup.page :refer [html5]]))

(defn render [{global-meta :meta posts :entries entry :entry}]
(html5 {:lang "en" :itemtype "http://schema.org/Blog"}
[:head
[:title (str (:site-title global-meta) "|" (:tag entry))]
[:meta {:charset "utf-8"}]
[:meta {:http-equiv "X-UA-Compatible" :content "IE=edge,chrome=1"}]
[:meta {:name "viewport" :content "width=device-width, initial-scale=1.0, user-scalable=no"}]]
[:body
[:h1 (str "Page " (:page entry))]
[:ul.items.columns.small-12
(for [post posts]
[:li (:title post)])]]))
162 changes: 126 additions & 36 deletions src/io/perun.clj
Original file line number Diff line number Diff line change
Expand Up @@ -753,16 +753,15 @@
paths (grouper (filter-meta-by-ext fileset options))]
(if (seq paths)
(reduce
(fn [result [path {:keys [entries group-meta]}]]
(fn [result [path {:keys [entry entries]}]]
(let [sorted (->> entries
(sort-by sortby comparator)
(map #(assoc % :content (->> (:path %)
(boot/tmp-get fileset)
boot/tmp-file
slurp))))
new-path (perun/create-filepath out-dir path)
new-entry (assoc group-meta :out-dir out-dir)]
(perun/report-info task-name (str "rendered " task-name " " path))
new-entry (assoc entry :out-dir out-dir)]
(assoc result new-path {:meta global-meta
:entry new-entry
:entries (vec sorted)})))
Expand All @@ -772,11 +771,84 @@
(perun/report-info task-name (str task-name " found nothing to render"))
[]))))

(def ^:private +collection-defaults+
(defn assortment-pre-wrap
"Handles common assortment task orchestration

`task-name` is used for log messages. `tracer` is a keyword that gets added
to the `:io.perun/trace` metadata. `grouper` is a function that takes a seq
of entries and returns a map of paths to render data (see docstring for
`assortment` for more info)

Returns a boot `with-pre-wrap` result"
[{:keys [task-name tracer grouper options]}]
(cond (not (fn? (:comparator options)))
(u/fail (str task-name " task :comparator option should implement Fn\n"))
(not (ifn? (:filterer options)))
(u/fail (str task-name " task :filterer option value should implement IFn\n"))
(not (ifn? (:sortby options)))
(u/fail (str task-name " task :sortby option value should implement IFn\n"))
(not (ifn? grouper))
(u/fail (str task-name " task :grouper option value should implement IFn\n"))
:else
(let [;; Make sure task-level metadata gets added to each entry
meta-grouper (fn [entries]
(->> entries
grouper
(map (fn [[path data]]
[path (update-in data [:entry] #(merge (:meta options) %))]))
(into {})))
options (assoc options :grouper meta-grouper)]
(render-pre-wrap {:task-name task-name
:render-paths-fn (partial grouped-paths task-name)
:options options
:tracer tracer}))))

(def ^:private +assortment-defaults+
{:out-dir "public"
:filterer identity
:extensions [".html"]
:sortby (fn [file] (:date-published file))
:comparator (fn [i1 i2] (compare i2 i1))
:grouper #(-> {"index.html" {:entries %}})})

(deftask assortment
"Render multiple collections
The symbol supplied as `renderer` should resolve to a function
which will be called with a map containing the following keys:
- `:meta`, global perun metadata
- `:entry`, the metadata for this collection
- `:entries`, all entries

The `grouper` function will be called with a seq containing the
entries to be grouped, and it should return a map with keys that
are filenames and values that are maps with the keys:
- `:entries`: the entries for each collection
- `:entry`: (optional) page metadata for this collection

Entries can optionally be filtered by supplying a function
to the `filterer` option.

The `sortby` function can be used for ordering entries before rendering."
[o out-dir OUTDIR str "the output directory"
r renderer RENDERER sym "page renderer (fully qualified symbol resolving to a function)"
g grouper GROUPER code "group posts function, keys are filenames, values are to-be-rendered entries"
_ filterer FILTER code "predicate to use for selecting entries (default: `identity`)"
e extensions EXTENSIONS [str] "extensions of files to include"
s sortby SORTBY code "sort entries by function"
c comparator COMPARATOR code "sort by comparator function"
m meta META edn "metadata to set on each collection entry"]
(let [grouper (or grouper #(-> {"index.html" {:entries %}}))
options (merge +assortment-defaults+ (dissoc *opts* :grouper))]
(assortment-pre-wrap {:task-name "assortment"
:tracer :io.perun/assortment
:grouper grouper
:options options})))

(def ^:private +collection-defaults+
{:out-dir "public"
:filterer identity
:extensions [".html"]
:sortby :date-published
:comparator (fn [i1 i2] (compare i2 i1))})

(deftask collection
Expand All @@ -790,51 +862,69 @@
Entries can optionally be filtered by supplying a function
to the `filterer` option.

The `sortby` and `groupby` functions can be used for ordering entries
The `sortby` function can be used for ordering entries
before rendering as well as rendering groups of entries to different pages."
[o out-dir OUTDIR str "the output directory"
r renderer RENDERER sym "page renderer (fully qualified symbol resolving to a function)"
_ filterer FILTER code "predicate to use for selecting entries (default: `identity`)"
e extensions EXTENSIONS [str] "extensions of files to include"
s sortby SORTBY code "sort entries by function"
g groupby GROUPBY code "group posts by function, keys are filenames, values are to-be-rendered entries"
c comparator COMPARATOR code "sort by comparator function"
p page PAGE str "collection result page path"
m meta META edn "metadata to set on each collection entry"]
(let [options (merge +collection-defaults+
(dissoc *opts* :page)
(if page
{:grouper #(-> {page {:entries %
:group-meta meta}})}
(if groupby
{:grouper #(->> %
(group-by groupby)
(map (fn [[page entries]]
[page {:entries entries
:group-meta meta}]))
(into {}))}
{:grouper #(-> {"index.html" {:entries %
:group-meta meta}})})))]
(cond (not (fn? (:comparator options)))
(u/fail "collection task :comparator option should implement Fn\n")
(not (ifn? (:filterer options)))
(u/fail "collection task :filterer option value should implement IFn\n")
(and (:page options) groupby)
(u/fail "using the :page option will render any :groupby option setting effectless\n")
(and (:groupby options) (not (ifn? (:groupby options))))
(u/fail "collection task :groupby option value should implement IFn\n")
(not (ifn? (:sortby options)))
(u/fail "collection task :sortby option value should implement IFn\n")
:else
(let [collection-paths (partial grouped-paths "collection")]
(render-pre-wrap {:task-name"collection"
:render-paths-fn collection-paths
:options options
:tracer :io.perun/collection})))))
(let [p (or page "index.html")]
(assortment-pre-wrap {:task-name "collection"
:tracer :io.perun/collection
:grouper #(-> {p {:entries %}})
:options (merge +collection-defaults+ (dissoc *opts* :page))})))

(def +inject-scripts-defaults+
{:extensions [".html"]})

(def ^:private +paginate-defaults+
{:out-dir "public"
:prefix "page-"
:page-size 10
:filterer identity
:extensions [".html"]
:sortby (fn [file] (:date-published file))
:comparator (fn [i1 i2] (compare i2 i1))})

(deftask paginate
"Render multiple collections
The symbol supplied as `renderer` should resolve to a function
which will be called with a map containing the following keys:
- `:meta`, global perun metadata
- `:entry`, the metadata for this collection
- `:entries`, all entries

Entries can optionally be filtered by supplying a function
to the `filterer` option.

The `sortby` function can be used for ordering entries before rendering."
[o out-dir OUTDIR str "the output directory"
f prefix PREFIX str "the prefix for each html file, eg prefix-1.html, prefix-2.html (default: `\"page-\"`)"
p page-size PAGESIZE int "the number of entries to include in each page (default: `10`)"
r renderer RENDERER sym "page renderer (fully qualified symbol resolving to a function)"
_ filterer FILTER code "predicate to use for selecting entries (default: `identity`)"
e extensions EXTENSIONS [str] "extensions of files to include"
s sortby SORTBY code "sort entries by function"
c comparator COMPARATOR code "sort by comparator function"
m meta META edn "metadata to set on each collection entry"]
(let [{:keys [sortby comparator page-size prefix] :as options} (merge +paginate-defaults+ *opts*)
grouper (fn [entries]
(->> entries
(sort-by sortby comparator)
(partition-all page-size)
(map-indexed #(-> [(str prefix (inc %1) ".html")
{:entry {:page (inc %1)}
:entries %2}]))
(into {})))]
(assortment-pre-wrap {:task-name "paginate"
:tracer :io.perun/paginate
:grouper grouper
:options options})))

(deftask inject-scripts
"Inject JavaScript scripts into html files.
Use either filter to include only files matching or remove to
Expand Down
Loading