Jon Aquino's Mental Garden

Engineering beautiful software jon aquino labs | personal blog

Tuesday, March 04, 2014

Lisphp at Ning - Sample Code

Here is the Lisp that I have written as an experiment with Lisphp. It is probably not great Lisp code—I don't have prior experience with Lisp—so any suggestions for improvement are welcome. I encourage others to make their Lisphp code publicly available so that we can all learn. Another Lisphp example I have found is balrog.

This code is for rendering an activity feed (like a Facebook Wall). It takes a bunch of activity-item objects, processes them, then feeds them into a Mustache template. The processing step sets up variables for the Mustache template to use.

For new Lisp programmers, I recommend the use of an editor plugin that automatically indents your Lisp code. See my first Lisphp blog post for related recommendations.


;;; Top-level module for rendering an activity feed for the network.
;;; @param string title  the title for the activity section
;;; @param array feed-events  the feed-event objects, parsed from JSON
;;; @param integer excerpt-length  the length at which to excerpt activity items
;;; @param string like-type  the naming scheme for likes: like, promote, or favorite
;;; @param string network-name  the name of the network
;;; @param string network-url  the URL of the network
;;; @param string network-icon-url  48x48 network icon
;;; @return string  HTML for the network feed

(import 'lib/components/activity/lib/process-feed-events.lisp')
(import 'lib/components/activity/lib/add-type-specific-properties.lisp')

;;; Filters, caches, and processes the given network feed events.
;;; @param array feed-events  the feed-event objects
;;; @param array options  options: excerpt-length
;;; @return array  the feed-event objects after processing
(define (process-feed-events feed-events options)
        ;; Remove rolled-up feed events for now, until we implement handling
        ;; for them.
        (setf! feed-events (remove-rollup-feed-events feed-events))
        (setf! feed-events (add-basic-properties feed-events options))
        (setf! feed-events (add-type-specific-properties feed-events options)))

(setf! processed-feed-events
       (process-feed-events feed-events
                            (hash 'excerpt-length'   excerpt-length
                                  'like-type'        like-type
                                  'network-name'     network-name
                                  'network-url'      network-url
                                  'network-icon-url' network-icon-url)))

;; Send the feed-events into the Mustache template.
((-> B renderMustache)
   'title' title
   'feed-events' processed-feed-events))


;;; Functions for processing activity events.

(use floor)
(use xg_elapsed_time)

;;; Removes rolled-up feed events. This is a temporary measure until we
;;; implement handling of rollups.
(define (remove-rollup-feed-events feed-events)
        (filter (lambda (feed-event)
                  (not (array-get feed-event 'rollUpType')))

;;; Adds basic properties, such as humanReadableDate, to each of the feed events
(define (add-basic-properties feed-events options)
        (map (lambda (feed-event)
               (let* ([content-id (array-get feed-event 'event' 'properties' 'contentId')])
                 (arr feed-event
                      (hash (event-type feed-event) true
                            'humanReadableDate'     (human-readable-date feed-event)
                            'content'               (to-content-properties content-id (at options 'excerpt-length'))))))

;;; Returns the event type suffixed with "Type", e.g., createBlogPostLikeType.
(define (event-type feed-event)
        (. (array-get feed-event 'event' 'eventType') 'Type'))

;;; Returns a friendly date for the event.
(define (human-readable-date feed-event)
          ;; Prefix timestamp with @ so that strtotime will understand it
          (. '@' (floor (/ (array-get feed-event 'event' 'createdDate') 1000)))
          nil nil false))


Post a Comment

<< Home