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.