This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-12-10
Channels
- # adventofcode (99)
- # architecture (10)
- # bangalore-clj (1)
- # beginners (65)
- # boot (9)
- # cider (78)
- # clojure (87)
- # clojure-austin (1)
- # clojure-brasil (13)
- # clojure-dev (14)
- # clojure-gamedev (3)
- # clojure-greece (2)
- # clojure-italy (2)
- # clojure-russia (18)
- # clojure-spec (26)
- # clojure-uk (15)
- # clojurescript (62)
- # core-logic (1)
- # cursive (1)
- # datomic (27)
- # emacs (17)
- # fulcro (2)
- # off-topic (44)
- # onyx (25)
- # perun (139)
- # re-frame (40)
- # reitit (2)
- # ring (4)
- # rum (2)
- # shadow-cljs (1)
- # slack-help (14)
- # unrepl (18)
@richiardiandrea I have finally had some time today for looking at these things. Your second question is easier (adding things to global metadata), so I'm going to start with that. Here's a task I've written to include recent posts in global metadata:
(deftask recent-posts
"Adds the `n` most recent posts to global metadata as `:recent-posts`"
[n num-posts NUMPOSTS int "The number of posts to store"]
(with-pre-wrap fileset
(let [options (merge +recent-posts-defaults+ *opts*)
global-meta (pm/get-global-meta fileset)
recent (->> (pm/get-meta fileset)
(filter post?)
(sort-by :date-published #(compare %2 %1))
(take (:num-posts options)))]
(perun/report-info "recent-posts" "added %s posts to metadata" (count recent))
(pm/set-global-meta fileset (assoc global-meta :recent-posts recent)))))
How to generalize that now :) because this can apply to any "global" properties you want to pass around in all website's pages
A few thoughts - I think you should be able to modify this to get tags from the entries instead. Also, I think maybe that your use-case should be an automatic feature of the tags
task.
Yep basically I need a task that let me append to global starting from the entries (no filtering)
Will start from the above
Maybe contribute back if I like what I am doing :)
for your other question about paginating the results of assortment
- it is possible to write a grouper
function that would do what you want, but it is not as easy out of the box as I'd like. I'm still thinking about how best to improve assortment
, but in the meantime, would an example of a grouper
function help?
@bhagany I think I will not paginate in the first version so low priority ;) I have a grouper function that does that..was just wondering whether I was missing something
It was such a nice experience to work with perun especially using Deraen's boot-livereload
The only thing is that I am compiling less at every watch so it is kind of a slower refreshing experience
I think perun should be able to help with that, if you wouldn't mind posting that less task
Yes no well, I rolled my own less task because I am using the js less compiler..but I haven't implemented the check for previously changed files
okay, you may want to look into using io.perun.content-task
- it is basically an abstraction of the file-watching pattern that you just need to plug a rendering function into
@bhagany oh that's cool
the task is this: https://github.com/degree9/boot-css/pull/1
so maybe I should chain the two somehow
@bhagany in the above, is post?
a perun function?
oh ok gotcha
can some meta on the fileset obj can be used as well? do we have any available?
yep, you can call io.perun.meta/get-global-meta
in any task to get the current global metadata
np π
so there is no metadata on each individual entry of the fileset, only "global" am I right?
ah that, right
so if I had a :post
entry I can just read that one
yeah, assuming you've put it there by some means, like metadata at the top of a markdown file, or meta
arguments passed to perun tasks
yep that was the plan π
but I guess I will stick to your task for now, I have a folder for the posts as well
and here you go, here is the other simple one:
(deftask all-tags
"Adds all the found tags as :all-tags global-meta"
[]
(with-pre-wrap fileset
(let [options (merge +recent-posts-defaults+ *opts*)
global-meta (pmeta/get-global-meta fileset)
all-tags (->> (pmeta/get-meta fileset)
(filter post?)
(mapcat :tags)
(vec))]
(pcore/report-info "all-tags" "added %s to metadata" all-tags)
(pmeta/set-global-meta fileset (assoc global-meta :all-tags all-tags)))))
I actually need dedupication there π
I don't think it does...
I was checking content-task
and I saw that it needs more things in there...
yeah, my intuition says that you'd be able to use other things that perun defines for those other arguments, but I'm not absolutely sure
also the all-tags
seems not to work because it needs to happen after rendering the posts...
uhm, actually even :recent-posts
does not display in the individual posts
I tried just now to render twice, I get a frankestain, but I see the tags and the posts
uhm...
in your case, you could do the initial render of the content that's unique to each page, then collect metadata, then render each again
let me bend my mind for a sec, not sure I get this π
so my second renderer would render only the menu/sidebar?
if that doesn't appeal to you, I think there's another way too, if you'd like to hear it
I'd like to, just to see if it is less code change
okay. is the metadata you need to generate your sidebar at the head of your markdown files?
yes, basically :tags
+ :recent-posts
for now
okay, if you take a look at the markdown task, you'll see that it's the composition of two simpler tasks: yaml-metadata
and markdown*
that would allow you to split up the work that markdown
does, so that metadata is collected, then you can run your custom tasks, and then markdown*
yep that would work for :tags
, not for :recent-posts
if I understand correctly
oh well
unless I only display :title
and :headline
uhm ok let me try first your suggestion
checking those tasks..
thanks a lot π really appreaciate!
@bhagany that first solution does not seem to work for me...I basically call a page
function already...which wraps...but moving the sidebar is not enough, the content also changes...rendering twice I thought would replace the file but for some reason it does not
yeah me too...I am investigating
it looks like the rendered the second time around has the content of the first render
yes so :content
now contains the whole html
You can take a look at the rendering functions for http://nicerthantriton.com to see
ok now I see why that works π
@bhagany sorry if I bombard
but it is not hmtl
I see now in :content
π
I see a string containing hiccup
now I do:
(perun/render :out-dir posts-dir :renderer ' :filterer post?)
(recent-posts)
(all-tags)
(perun/render :out-dir posts-dir :renderer ')
i see you are doing an into
the second time in page
so I was expecting hiccup in there...
oh wait
so the first time :content
is set to whatever the first render returns
is it converted to string?
yeah it looks like your return html5
stuff from post...
before I modified render
to work this way, I used function composition to achieve what I wanted, and in that case, I think that content was a hiccup data structure
if my first renderer wrap thing with hiccup.core/html5
, then I receive hiccup
as data in the second render
so this works:
(defn render-content [{global-meta :meta entries :entries entry :entry}]
(html5 ;; I should not need this, maybe perun bug?
[:div.twelve.wide.column
"<!-- Post -->"
[:div.ui.right.floated.basic.segment
[:div.ui.compact.segments
[:div.ui.segment
[:a.ui.medium.image {:href (:canonical-url entry)}
[:img {:src (or (:image entry) "")}]]]
(when-let [sponsor-img (:sponsor-image entry)]
[:div.ui.right.aligned.basic.secondary.segment
[:div "Sponsored by"
[:a.ui.tiny.image {:href (:sponsor-url entry)}
[:img {:src sponsor-img}]]]])]]
[:div (:content entry)]
"<!-- End Post -->"]))
(defn render-page [{global-meta :meta entries :entries entry :entry}]
(let [all-tags (or (:all-tags entry) (into #{} (mapcat :tags) entries))
latest-posts (or (:latest-posts entry) (take 3 entries))
active-tags (->> [(:tag entry)] (keep identity) (into #{}))]
(base/page
global-meta
[:div.ui.centered.main.stackable.reverse.grid.container {:role "content"}
(:content entry) ;; will receive the html from render-content above
"<!-- Sidebar -->"
(base/sidebar all-tags latest-posts active-tags)
"<!-- End Sidebar -->"])))
yep in render-content
okay, yeah, render
isn't tied to any particular html renderer, so it's up to you to figure out how you want to return html
but the return of your render function needs to be the string that you want written to the file
so :content
just needs to be a string
let me try one thing
@bhagany fun!
(ns
(:require [clojure.edn :as edn]
[com.andrearichiardi.blog.base :as base]))
(defn render-content [{global-meta :meta entries :entries entry :entry}]
(pr-str
[:div.twelve.wide.column
"<!-- Post -->"
[:div.ui.right.floated.basic.segment
[:div.ui.compact.segments
[:div.ui.segment
[:a.ui.medium.image {:href (:canonical-url entry)}
[:img {:src (or (:image entry) "")}]]]
(when-let [sponsor-img (:sponsor-image entry)]
[:div.ui.right.aligned.basic.secondary.segment
[:div "Sponsored by"
[:a.ui.tiny.image {:href (:sponsor-url entry)}
[:img {:src sponsor-img}]]]])]]
[:div (:content entry)]
"<!-- End Post -->"]))
(defn render-page [{global-meta :meta entries :entries entry :entry}]
(let [all-tags (or (:all-tags entry) (into #{} (mapcat :tags) entries))
latest-posts (or (:latest-posts entry) (take 3 entries))
active-tags (->> [(:tag entry)] (keep identity) (into #{}))]
(base/page
global-meta
[:div.ui.centered.main.stackable.reverse.grid.container {:role "content"}
(edn/read-string (:content entry)) ;; will receive the html from render-content above
"<!-- Sidebar -->"
(base/sidebar all-tags latest-posts active-tags)
"<!-- End Sidebar -->"])))
yes pr-str
outputs clojure data
I feel better to have data there π
this could be a topic for my new blog π
you could serialize and pass a function over π
other question...sometimes yaml errors out with:
ll; mapping values are not allowed here; in 'string', line 4, column 87:
... in a GitHub blog? The answer is: of course you can! At the end ...
^
problem: "mapping values are not allowed here"
problemMark: #object[org.yaml.snakeyaml.error.Mark 0x5cf45f80 " in 'string', line 4, column 87:\n ... in a GitHub blog? The answer is: of course you can! At the end ... \n ^"]
ah maybe a character that means something