Make add-injection support more complex injections. Thanks @PuercoPop.

In short, an injection is now a FUNCTION that takes a
document and returns either a STRING to insert in the
page (possibly with data from the document) or NIL.
This commit is contained in:
Brit Butler 2014-09-22 14:26:20 -04:00
parent f474db77b2
commit e44d0bde9e
7 changed files with 28 additions and 27 deletions

View file

@ -4,13 +4,16 @@
instead of the previous symlinked, timestamped deploy strategy.
To retain the previous behavior, add `(versioned)` to your config's
`:plugins` list.
* **SITE-BREAKING CHANGE**: Custom themes will be broken by a change
* **Incompatible Change**: Custom themes will be broken by a change
to URL handling. Previously, we were hand-constructing URLs in the
templates. All site objects now store their URL in an instance slot.
In general, hrefs should be of the form `<a href="{$config.domain}/{$obj.url}"> ...</a>`.
* **Incompatible Change**: The interface of the `add-injection` function
has changed. If you have written a plugin which uses `add-injection`
you should update it to conform to the [new interface][add-inj-new].
* **Docs**: Improved README and Theming docs. New Config File docs.
* Changes to `:routing` would previously break links in the templates
but now work seamlessly due to the updated URL handling.
* **Docs**: Improved README and Theming docs. New Config File docs.
* Loading content is more robust when empty lines or metadata are passed.
Thanks to @PuercoPop for the bug report and preliminary fix.
* The config `:repo` option is now deprecated as its value has become
@ -21,6 +24,8 @@
* The templates are now HTML5 valid thanks to @Ferada.
* Fixed a bug where RSS/Atom tag feeds were being published multiple times.
[add-inj-new]: https://github.com/redline6561/coleslaw/blob/master/docs/plugin-api.md#extension-points
## Changes for 0.9.5 (2014-06-13):
* A plugin for Incremental builds, cutting runtime for generating

View file

@ -213,7 +213,7 @@ order. Feeds exist to special case RSS and ATOM generation.
Currently, there is only 1 content type: POST, for blog entries.
PAGE, a content type for static page support, is available as a plugin.
## Areas for Improvement
## Areas for Improvement (i.e. The Roadmap)
### TODO for 0.9.6

View file

@ -15,14 +15,12 @@
# Extension Points
* **New functionality via JS**, for example the Disqus and Mathjax
plugins. In this case, the plugin's `enable` function should call
* **New functionality via JS**, for example the Disqus and Mathjax plugins.
In this case, the plugin's `enable` function should call
[`add-injection`](http://redlinernotes.com/docs/coleslaw.html#add-injection_func)
with an injection and a keyword. The injection itself is a list of
the string to insert and a lambda or function that can be called on
a content instance to determine whether the injection should be
included on the page. The keyword specifies whether the injected
text goes in the HEAD or BODY element. The
with an injection and a keyword. The injection is a function that takes a
*Document* and returns a string to insert in the page or nil.
The keyword specifies whether the injected text goes in the HEAD or BODY element. The
[Disqus plugin](http://github.com/redline6561/coleslaw/blob/master/plugins/disqus.lisp)
is a good example of this.

View file

@ -21,4 +21,5 @@
</script>")
(defun enable (&key tracking-code)
(add-injection (format nil *analytics-js* tracking-code) :head))
(let ((snippet (format nil *analytics-js* tracking-code)))
(add-injection (constantly snippet) :head)))

View file

@ -24,5 +24,7 @@
<a href=\"http://disqus.com\" class=\"dsq-brlink\">comments powered by <span class=\"logo-disqus\">Disqus</span></a>")
(defun enable (&key shortname)
(add-injection (list (format nil *disqus-header* shortname)
(lambda (x) (typep x 'post))) :body))
(flet ((inject-p (x)
(when (typep x 'post)
(format nil *disqus-header* shortname))))
(add-injection #'inject-p :body)))

View file

@ -24,6 +24,7 @@
(defun enable (&key force config (preset "TeX-AMS-MML_HTMLorMML")
(location "http://cdn.mathjax.org/mathjax/latest/MathJax.js"))
(flet ((plugin-p (x) (or force (mathjax-p x))))
(let ((mathjax-header (format nil *mathjax-header* config location preset)))
(add-injection (list mathjax-header #'plugin-p) :head))))
(flet ((inject-p (x)
(when (or force (mathjax-p x))
(format nil *mathjax-header* config location preset))))
(add-injection #'inject-p :head)))

View file

@ -4,21 +4,15 @@
"A list that stores pairs of (string . predicate) to inject in the page.")
(defun add-injection (injection location)
"Adds an INJECTION to a given LOCATION for rendering. The INJECTION should be
a string which will always be added or a (string . lambda). In the latter case,
the lambda takes a single argument, a content object, i.e. a POST or INDEX, and
any return value other than nil indicates the injection should be added."
(let ((result (etypecase injection
(string (list injection #'identity))
(list injection))))
(push result (getf *injections* location))))
"Adds an INJECTION to a given LOCATION for rendering. The INJECTION should be a
function that takes a DOCUMENT and returns NIL or a STRING for template insertion."
(push result (getf *injections* location)))
(defun find-injections (content)
"Iterate over *INJECTIONS* collecting any that should be added to CONTENT."
(flet ((injections-for (location)
(loop for (injection predicate) in (getf *injections* location)
when (funcall predicate content)
collect injection)))
(loop for injection in (getf *injections* location)
collecting (funcall injection content))))
(list :head (injections-for :head)
:body (injections-for :body))))