Add RSS support.
* haunt/builder/rss.scm: New file with support for RSS feeds. * Makefile.am: Add it.
This commit is contained in:
		
				
					committed by
					
						
						David Thompson
					
				
			
			
				
	
			
			
			
						parent
						
							15c4605e1d
						
					
				
				
					commit
					8891da0e3a
				
			@@ -54,6 +54,7 @@ SOURCES =					\
 | 
				
			|||||||
  haunt/builder/assets.scm			\
 | 
					  haunt/builder/assets.scm			\
 | 
				
			||||||
  haunt/builder/atom.scm			\
 | 
					  haunt/builder/atom.scm			\
 | 
				
			||||||
  haunt/builder/blog.scm			\
 | 
					  haunt/builder/blog.scm			\
 | 
				
			||||||
 | 
					  haunt/builder/rss.scm				\
 | 
				
			||||||
  haunt/reader.scm				\
 | 
					  haunt/reader.scm				\
 | 
				
			||||||
  haunt/reader/texinfo.scm			\
 | 
					  haunt/reader/texinfo.scm			\
 | 
				
			||||||
  haunt/ui.scm					\
 | 
					  haunt/ui.scm					\
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										107
									
								
								haunt/builder/rss.scm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								haunt/builder/rss.scm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					;;; Haunt --- Static site generator for GNU Guile
 | 
				
			||||||
 | 
					;;; Copyright © 2018 Christopher Lemmer Webber <cwebber@dustycloud.org>
 | 
				
			||||||
 | 
					;;;
 | 
				
			||||||
 | 
					;;; This file is part of Haunt.
 | 
				
			||||||
 | 
					;;;
 | 
				
			||||||
 | 
					;;; Haunt is free software; you can redistribute it and/or modify it
 | 
				
			||||||
 | 
					;;; under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					;;; the Free Software Foundation; either version 3 of the License, or
 | 
				
			||||||
 | 
					;;; (at your option) any later version.
 | 
				
			||||||
 | 
					;;;
 | 
				
			||||||
 | 
					;;; Haunt is distributed in the hope that it will be useful, but
 | 
				
			||||||
 | 
					;;; WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
				
			||||||
 | 
					;;; General Public License for more details.
 | 
				
			||||||
 | 
					;;;
 | 
				
			||||||
 | 
					;;; You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					;;; along with Haunt.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;;; Commentary:
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					;; RSS feed builder.
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					;;; Code:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define-module (haunt builder rss)
 | 
				
			||||||
 | 
					  #:use-module (srfi srfi-19)
 | 
				
			||||||
 | 
					  #:use-module (srfi srfi-26)
 | 
				
			||||||
 | 
					  #:use-module (ice-9 match)
 | 
				
			||||||
 | 
					  #:use-module (sxml simple)
 | 
				
			||||||
 | 
					  #:use-module (haunt site)
 | 
				
			||||||
 | 
					  #:use-module (haunt post)
 | 
				
			||||||
 | 
					  #:use-module (haunt page)
 | 
				
			||||||
 | 
					  #:use-module (haunt utils)
 | 
				
			||||||
 | 
					  #:use-module (haunt html)
 | 
				
			||||||
 | 
					  #:use-module (haunt serve mime-types)
 | 
				
			||||||
 | 
					  #:use-module (haunt builder atom)
 | 
				
			||||||
 | 
					  #:export (rss-feed))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;; Reader beware: this isn't as nice as atom.scm, because rss isn't
 | 
				
			||||||
 | 
					;; as nice as atom.  Worse beats better on the play field again...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;; RFC 822 dates are inferior to ISO 8601, but it's
 | 
				
			||||||
 | 
					;; what RSS wants, so...
 | 
				
			||||||
 | 
					(define (date->rfc822-str date)
 | 
				
			||||||
 | 
					  (date->string date "~a, ~d ~b ~Y ~T ~z"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (sxml->xml* sxml port)
 | 
				
			||||||
 | 
					  "Write SXML to PORT, preceded by an <?xml> tag."
 | 
				
			||||||
 | 
					  (display "<?xml version=\"1.0\" encoding=\"utf-8\"?>" port)
 | 
				
			||||||
 | 
					  (sxml->xml sxml port))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define* (post->rss-item site post #:key (blog-prefix ""))
 | 
				
			||||||
 | 
					  "Convert POST into an RSS <item> node."
 | 
				
			||||||
 | 
					  `(item
 | 
				
			||||||
 | 
					    (title ,(post-ref post 'title))
 | 
				
			||||||
 | 
					    ;; Looks like: <author>lawyer@boyer.net (Lawyer Boyer)</author>
 | 
				
			||||||
 | 
					    (author
 | 
				
			||||||
 | 
					     ,(let ((email (post-ref post 'email))
 | 
				
			||||||
 | 
					            (author (post-ref post 'author)))
 | 
				
			||||||
 | 
					        (string-append (if email
 | 
				
			||||||
 | 
					                           (string-append email " ")
 | 
				
			||||||
 | 
					                           "")
 | 
				
			||||||
 | 
					                       (if author
 | 
				
			||||||
 | 
					                           (string-append "(" author ")")
 | 
				
			||||||
 | 
					                           ""))))
 | 
				
			||||||
 | 
					    (pubDate ,(date->rfc822-str (post-date post)))
 | 
				
			||||||
 | 
					    (link (@ (href ,(string-append blog-prefix "/"
 | 
				
			||||||
 | 
					                                   (site-post-slug site post) ".html"))
 | 
				
			||||||
 | 
					             (rel "alternate")))
 | 
				
			||||||
 | 
					    (description ,(sxml->html-string (post-sxml post)))
 | 
				
			||||||
 | 
					    ,@(map (lambda (enclosure)
 | 
				
			||||||
 | 
					             `(enclosure (@ (title ,(enclosure-title enclosure))
 | 
				
			||||||
 | 
					                            (url ,(enclosure-url enclosure))
 | 
				
			||||||
 | 
					                            (type ,(enclosure-mime-type enclosure))
 | 
				
			||||||
 | 
					                            ,@(map (match-lambda
 | 
				
			||||||
 | 
					                                     ((key . value)
 | 
				
			||||||
 | 
					                                      (list key value)))
 | 
				
			||||||
 | 
					                                   (enclosure-extra enclosure)))))
 | 
				
			||||||
 | 
					           (post-ref-all post 'enclosure))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define* (rss-feed #:key
 | 
				
			||||||
 | 
					                   (file-name "rss-feed.xml")
 | 
				
			||||||
 | 
					                   (subtitle "Recent Posts")
 | 
				
			||||||
 | 
					                   (filter posts/reverse-chronological)
 | 
				
			||||||
 | 
					                   (max-entries 20)
 | 
				
			||||||
 | 
					                   (blog-prefix ""))
 | 
				
			||||||
 | 
					  "Return a builder procedure that renders a list of posts as an RSS
 | 
				
			||||||
 | 
					feed.  All arguments are optional:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FILE-NAME: The page file name
 | 
				
			||||||
 | 
					SUBTITLE: The feed subtitle
 | 
				
			||||||
 | 
					FILTER: The procedure called to manipulate the posts list before rendering
 | 
				
			||||||
 | 
					MAX-ENTRIES: The maximum number of posts to render in the feed"
 | 
				
			||||||
 | 
					  (lambda (site posts)
 | 
				
			||||||
 | 
					    (make-page file-name
 | 
				
			||||||
 | 
					               `(rss (@ (version "2.0"))
 | 
				
			||||||
 | 
					                     (channel
 | 
				
			||||||
 | 
					                      (title ,(site-title site))
 | 
				
			||||||
 | 
					                      ;; It looks like RSS's description and atom's subtitle
 | 
				
			||||||
 | 
					                      ;; are equivalent?
 | 
				
			||||||
 | 
					                      (description ,subtitle)
 | 
				
			||||||
 | 
					                      (pubDate ,(date->rfc822-str (current-date)))
 | 
				
			||||||
 | 
					                      (link (@ (href ,(site-domain site))))
 | 
				
			||||||
 | 
					                      ,@(map (cut post->rss-item site <>
 | 
				
			||||||
 | 
					                                  #:blog-prefix blog-prefix)
 | 
				
			||||||
 | 
					                             (take-up-to max-entries (filter posts)))))
 | 
				
			||||||
 | 
					               sxml->xml*)))
 | 
				
			||||||
		Reference in New Issue
	
	Block a user