Clojure library offering a few helpful extensions to the popular Specter for selecting and transforming Hiccup data using simple CSS selectors.
First add Specter as a dependency to your project. Then add the following dep to your project or deps file:
First be sure to include the relevant libraries:
(require '[com.rpl.specter :as specter])
(require '[inspecter.core :as i])
Find a Hiccup element by its id:
(def hiccup
[:div
[:h1#zero "My Title"]
[:h2#one {:data-attr "one"} "Hello"]
[:h2#two {:data-attr "two"} "World"]])
user=> (specter/select [(i/matches "#two")] hiccup)
[[:h2#two {:data-attr "one"} "World"]]
Specter's select
function returns a vector of ALL items that match the selector.
Push it a little further and grab the attribute maps for every h2
:
user=> (specter/select [(i/matches "h2") i/ATTRS] hiccup)
[{:data-attr "one"}
{:data-attr "two"}]
Most importantly, though, is Specter's ability to navigate to items in collections and update them in place. This library makes updating Hiccup in place easy:
(def hiccup
[:div
[:h1 "My Title"]
[:h2.find-me "My Subtitle"]])
user=> (specter/transform
[(inspect/matches ".find-me") inspect/ATTRS]
(inspect/update-attrs #(assoc % :changed :me))
hiccup)
[:div
[:h1 "My Title"]
[:h2.find-me {:changed :me} "My Subtitle"]]
Inspecter exposes the following functions for Hiccup path navigation and transformation:
inspecter.core/matches
- Returns a recursive path navigatorinspecter.core/ATTRS
- Path navigator to an element's attributes.inspecter.core/CONTENTS
- Path navigator to an element's contents.inspecter.core/update-attrs
- Helper for updating an element's attributes.
Inspecter matches Hiccup elements via simple, limited-scope CSS selectors. While the universe of potential CSS selectors is enormous, Inspecter implements a narrow set for tag, id, and class matching. These are each supported:
*
- Matches every elementdiv
- Matches all[:div ...]
elementsnav#main
- Matches all[:nav {:id "main"} ...]
or[:nav#main ...]
div.small.button
- Matches all[:div.small.button]
or[:div {:class "small button"} ...]
elementsdiv[hello=world]
- Matches all[:div {:hello "world"} ...]
elements
Distributed under the MIT License.