Skip to content

Commit

Permalink
Fix Cookbook link
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Holy committed Mar 19, 2014
1 parent e19ed43 commit 68e248c
Showing 1 changed file with 2 additions and 124 deletions.
126 changes: 2 additions & 124 deletions README.md
Expand Up @@ -6,7 +6,7 @@ David Nolen wrote a [nice tutorial](http://github.com/swannodette/enlive-tutoria

Another [tutorial](https://github.com/cgrand/enlive/wiki/Table-and-Layout-Tutorial,-Part-1:-The-Goal by Brian Marick) is by Brian Marick.

There's a quickstart section in [Clojure Cookbook](https://github.com/clojure-cookbook/clojure-cookbook/blob/master/webapps/templating-with-enlive/templating-with-enlive.asciidoc).
There's a quickstart section in [Clojure Cookbook](https://github.com/clojure-cookbook/clojure-cookbook/blob/master/07_webapps/7-11_enlive.asciidoc).

## Where do I get support?

Expand Down Expand Up @@ -254,126 +254,4 @@ A step is a predicate, for example `:h1`, `:p.some-class` or even
To select elements which match several predicates, you need to group
predicates into a vector: *inside steps, vectors mean "and"*. This may seem
confusing but the rule is simple: the outer-most vector hierarchically
chains steps, all other vectors denote intersection (and) between steps.

So `[:p (attr? :lang)]` is going to match any elements with a `lang` attribute
inside a `:p` element. On the other hand, `[[:p (attr? :lang)]]` is going to match
any `p` with a `lang` attribute.

Similarly, sets group predicates in an union. Hence *inside steps, sets mean
"or"*. So `[#{:div.class1 :div.class2}]` match every `div` which has either
`class1` or `class2`. This can alternatively be written
as `[[:div #{:.class1 .class2}]]`. Indeed you can have nested "ors" and "ands"
which means nested sets and vectors.

At the top level you can have a big "or" between selectors by wrapping several
selectors in a set. `#{[:td :em] [:th :em]}` is going to match any `em` insides
either a `th` or a `td`. This is equivalent to `[#{:td :th} :em]`.

### Selector Syntax

See [syntax.html](http://enlive.cgrand.net/syntax.html)

Some examples:

```
Enlive CSS
=======================================================
[:div] div
[:body :script] body script
#{[:ul.outline :> :li] [:ol.outline :> li]} ul.outline > li, ol.outline > li
[#{:ul.outline :ol.outline} :> :li] ul.outline > li, ol.outline > li
[[#{:ul :ol} :.outline] :> :li] ul.outline > li, ol.outline > li
[:div :> :*] div > *
[:div :> text-node] (text children of a div)
[:div :> any-node] (all children (including text nodes and comments) of a div)
{[:dt] [:dl]} (fragments starting by DT and ending at the *next* DD)
```

## The `at` form

The `at` form is the most important form in Enlive. There are implicit `at`
forms in `snippet` and `template`.

```clojure
(at a-node
[:a :selector] a-transformation
[:another :selector] another-transformation
;; ...
)
```

The right-hand value of a rule can be `nil`. It's the idiomatic way to remove an
element.

Transformations are closures which take one arg (the selected node) and return
`nil`, another node or an arbitrarily nested collection of nodes.

Rules are applied top-down: the first rule transforms the whole tree and the
resulting tree is passed to the next rules.

## Transformations

A transformation is a function that returns either a node or collection of node.

Enlive defines several helper functions:
```clojure
;; Replaces the content of the element. Values can be nodes or collection of nodes.
(content "xyz" a-node "abc")

;; Replaces the content of the element. Values are strings containing html code.
(html-content "<blink>please no</blink>")

;; Wraps selected node into the given tag
(wrap :div)
;; or
(wrap :div {:class "foo"})

;; Opposite to wrap, returns the content of the selected node
unwrap

;; Sets given key value pairs as attributes for selected node
(set-attr :attr1 "val1" :attr2 "val2")

;; Removes attribute(s) from selected node
(remove-attr :attr1 :attr2)

;; Adds class(es) to the selected node
(add-class "foo" "bar")

;; Removes class(es) from the selected node
(remove-class "foo" "bar")

;; Chains (composes) several transformations. Applies functions from left to right.
(do-> transformation1 transformation2)

;; Clones the selected node, applying transformations to it.
(clone-for [item items] transformation)
;; or
(clone-for [item items]
selector1 transformation1
selector2 transformation2)

;; Appends the values to the content of the selected element.
(append "xyz" a-node "abc")

;; Prepends the values to the content of the selected element.
(prepend "xyz" a-node "abc")

;; Inserts the values after the current selection (node or fragment).
(after "xyz" a-node "abc")

;; Inserts the values before the current selection (node or fragment).
(before "xyz" a-node "abc")

;; Replaces the current selection (node or fragment).
(substitute "xyz" a-node "abc")

;; Takes all nodes (under the current element) matched by src-selector, removes
;; them and combines them with the elements matched by dest-selector.
(move [:.footnote] [:#footnotes] content)
```

## Known limitations/problems

* No namespaces support (hence unsuitable for most XML)
chains steps, a

5 comments on commit 68e248c

@simlun
Copy link

@simlun simlun commented on 68e248c Mar 23, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oopsie? :)

@holyjak
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for spotting this, @simlun (though I could be more specific in your comment - for people like me that get only the comment by email).

I have no idea why is there the deletion, I essentially just edited the README at github and changed the link. Some internet gnomes perhaps .... . @cgrand can you please revert the commit and fix the link manually? Sorry for the inconvenience.

@cgrand
Copy link
Owner

@cgrand cgrand commented on 68e248c Mar 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakubholynet @simlun thanks, it will teach me to screen PR on a phone.

@simlun
Copy link

@simlun simlun commented on 68e248c Mar 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jakubholynet I'll be more specific next time! Yah, I think those pesky Internet gnomes feed on JavaScript... Getting fatter and fatter each day ;)

@holyjak
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cgrand It has tought me to review my changes before sending a PR :-) So in total this was a useful, educational experience for everybody involved. win - win :-) (I am really happy that @simlun has spotted the deletion)

Please sign in to comment.