I'm experimenting with Enlive, and it's really great! Thanks a lot for creating such an ingenious library!
However, I have at least one need that it doesn't seem to address "out of the box". Suppose a web designer has created me a bunch of nice user interface components, which have sections of identical markup. For example, there could be a list of labeled radio buttons along with another list which is the same except for a text field in the end for "other". I'd like to avoid duplicating the common part, but defsnippet apparently requires me to define the nodes and the transformations together.
So, the markup could be something like this:
<html>
<body>
<div id="labeled-choices-without-other">
<!-- Static stuff here -->
<div class="text">Text</div>
<input type="radio" name="a" value="1"><label>Choice</label><br>
<!-- Static stuff here -->
</div>
<hr>
<div id="labeled-choices-with-other">
<!-- Static stuff here -->
<div class="text">Text</div>
<input type="radio" name="b" value="1"><label>Choice</label><br>
<input type="radio" name="b" value="2"><label>Something else</label><input name="c" size="10">
<!-- Static stuff here -->
</div>
</body>
</html>
Creating the second type of radio button list (#labeled-choices-with-other) would be exactly like creating the first type (#labeled-choices-without-other), except for the additional step of transforming the last row. I think I managed to get rid of the duplication (at least in this toy example) with two additional macros:
;; like defsnippet, but the nodes aren't specified yet
(defmacro deftransfs [name args & forms]
`(def ~name
(fn [nodes# ~@args]
(flatmap (transformation ~@forms) nodes#))))
;; fixes the nodes to transform and combines the transformations
(defmacro compose-snippet [name source selector & transfs]
(let [args (gensym "args")]
`(def ~name
(fn [~args]
~(reduce
#(list %2 %1 args)
`(~(first transfs) (select (html-resource ~source) ~selector) ~args)
(rest transfs))))))
With these, I can create my "snippets" as follows:
;; list of radio buttons with labels, transformations only
(deftransfs labeled-choices [{:keys [item choices]}]
[:.text] (content item)
{[:input][:br]} (clone-for [x choices]
[:input] (set-attr :name item, :value x)
[:label] (content x)))
;; single radio button & label with a text field, transformations only
(deftransfs other-choice [{:keys [item other]}]
[[:input (nth-last-of-type 2)]] (set-attr :name item, :value other)
[[:label last-of-type]] (content other)
[[:input last-of-type]] (set-attr :name other))
;; associates nodes with one set of transformations
(compose-snippet labeled-choices-without-other
"catalog.html" [:#labeled-choices-without-other]
labeled-choices)
;; associates nodes with two sets of transformations
(compose-snippet labeled-choices-with-other
"catalog.html" [:#labeled-choices-with-other]
labeled-choices other-choice)
Being something of a newbie, I'd like to ask if this is a reasonable approach? If it is, would it by any chance be worthwhile to support something similar in a future version of Enlive?
Best regards,
Miikka
However, I have at least one need that it doesn't seem to address "out of the box". Suppose a web designer has created me a bunch of nice user interface components, which have sections of identical markup. For example, there could be a list of labeled radio buttons along with another list which is the same except for a text field in the end for "other". I'd like to avoid duplicating the common part, but defsnippet apparently requires me to define the nodes and the transformations together.
;; list of radio buttons with labels, transformations only
(deftransfs labeled-choices [{:keys [item choices]}]
[:.text] (content item)
{[:input][:br]} (clone-for [x choices]
[:input] (set-attr :name item, :value x)
[:label] (content x)))
;; single radio button & label with a text field, transformations only
(deftransfs other-choice [{:keys [item other]}]
[[:input (nth-last-of-type 2)]] (set-attr :name item, :value other)
[[:label last-of-type]] (content other)
[[:input last-of-type]] (set-attr :name other))
;; associates nodes with one set of transformations
(compose-snippet labeled-choices-without-other
"catalog.html" [:#labeled-choices-without-other]
labeled-choices)
;; associates nodes with two sets of transformations
(compose-snippet labeled-choices-with-other
"catalog.html" [:#labeled-choices-with-other]
labeled-choices other-choice)
--
You received this message because you are subscribed to the Google Groups "Enlive" group.
To post to this group, send email to enliv...@googlegroups.com.
To unsubscribe from this group, send email to enlive-clj+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/enlive-clj?hl=en.