diff --git a/docs/plugin-use.md b/docs/plugin-use.md index 2a380e3..025112a 100644 --- a/docs/plugin-use.md +++ b/docs/plugin-use.md @@ -55,3 +55,9 @@ **Description**: Import blog posts from Wordpress using their export tool. Blog entries will be read from the XML and converted into .post files. Afterwards the XML file will be deleted to prevent reimporting. Optionally an ```:output``` argument may be supplied to the plugin. If provided, it should be a directory in which to store the .post files. Otherwise, the value of ```:repo``` in your .coleslawrc will be used. **Example**: ```(import :filepath "/home/redline/redlinernotes-export.timestamp.xml" :output "/home/redlinernotes/blog/")``` + +## Sitemap generator + +**Description**: this plugin generates a sitemap.xml under the page root, which is useful if you want google to crawl your site. + +**Example**: ```(sitemap)``` diff --git a/plugins/sitemap.lisp b/plugins/sitemap.lisp new file mode 100644 index 0000000..ef8cbaa --- /dev/null +++ b/plugins/sitemap.lisp @@ -0,0 +1,29 @@ +(defpackage :coleslaw-sitemap + (:use :cl) + (:import-from :coleslaw + #:*config* + #:deploy + #:domain + #:find-all + #:page-url + #:rel-path + #:staging-dir + #:theme-fn + #:write-page) + (:export #:enable)) + +(in-package :coleslaw-sitemap) + +(defmethod deploy :before (staging) + "Render sitemap.xml under document root" + (let* ((urls (append '("" "sitemap.xml") ; empty string is for root url + (mapcar #'page-url (find-all 'coleslaw:post))))) + (write-page (rel-path (staging-dir *config*) "sitemap.xml") + (funcall (theme-fn :sitemap "feeds") + (list :domain (domain *config*) + :urls urls + :pubdate (local-time:format-rfc3339-timestring + nil + (local-time:now))))))) + +(defun enable ()) diff --git a/src/coleslaw.lisp b/src/coleslaw.lisp index f627279..25c6b73 100644 --- a/src/coleslaw.lisp +++ b/src/coleslaw.lisp @@ -12,14 +12,18 @@ (with-output-to-string (str) (3bmd:parse-string-and-print-to-stream text str))))) -(defgeneric page-path (object) - (:documentation "The path to store OBJECT at once rendered.")) +(defgeneric page-url (object) + (:documentation "The url to the object, without the domain")) -(defmethod page-path :around ((object t)) +(defmethod page-url :around ((object t)) (let ((result (call-next-method))) - (if (pathname-type result) - result - (make-pathname :type "html" :defaults result)))) + (namestring (if (pathname-type result) + result + (make-pathname :type "html" :defaults result))))) + +(defun page-path (object) + "The path to store OBJECT at once rendered." + (rel-path (staging-dir *config*) (page-url object))) (defun render-page (content &optional theme-fn &rest render-args) "Render the given CONTENT to disk using THEME-FN if supplied. diff --git a/src/indices.lisp b/src/indices.lisp index 818b8a6..a28ef50 100644 --- a/src/indices.lisp +++ b/src/indices.lisp @@ -17,14 +17,14 @@ (defclass date-index (index) ()) (defclass int-index (index) ()) -(defmethod page-path ((object index)) - (rel-path (staging-dir *config*) (index-id object))) -(defmethod page-path ((object tag-index)) - (rel-path (staging-dir *config*) "tag/~a" (index-id object))) -(defmethod page-path ((object date-index)) - (rel-path (staging-dir *config*) "date/~a" (index-id object))) -(defmethod page-path ((object int-index)) - (rel-path (staging-dir *config*) "~d" (index-id object))) +(defmethod page-url ((object index)) + (index-id object)) +(defmethod page-url ((object tag-index)) + (format nil "tag/~a" (index-id object))) +(defmethod page-url ((object date-index)) + (format nil "date/~a" (index-id object))) +(defmethod page-url ((object int-index)) + (format nil "~d" (index-id object))) (defun all-months () "Retrieve a list of all months with published content." diff --git a/src/posts.lisp b/src/posts.lisp index 5301ab1..4962054 100644 --- a/src/posts.lisp +++ b/src/posts.lisp @@ -10,8 +10,8 @@ :prev prev :next next))) -(defmethod page-path ((object post)) - (rel-path (staging-dir *config*) "posts/~a" (content-slug object))) +(defmethod page-url ((object post)) + (format nil "posts/~a" (content-slug object))) (defmethod initialize-instance :after ((object post) &key) (with-accessors ((title post-title) diff --git a/themes/sitemap.tmpl b/themes/sitemap.tmpl new file mode 100644 index 0000000..89b77bb --- /dev/null +++ b/themes/sitemap.tmpl @@ -0,0 +1,13 @@ +{namespace coleslaw.theme.feeds} + +{template sitemap} +{\n} + + {foreach $url in $urls} + + {$domain}/{$url} + {$pubdate} + + {/foreach} + +{/template}