Jon Aquino's Mental Garden

Wednesday, March 19, 2014

Mustache: How to test for existence without iteration

In Mustache templates, sometimes you just want to test if an array exists, without iterating over it. However, {{#myArray}}...{{/myArray}} will iterate over myArray. What if you just want to check if myArray exists?

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.

render-network-feed.lisp

;;; 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

environment: this is the Lisp environment itself added as a variable, to allow you to check if a function exists: (exists-at? environment 'my-function')

Here is the code that we use to call Lisphp. Note that you have a choice of runFile() or runCode(); also note the custom functions. You may need to make some modifications to get this to run in your own environment:

An example of Lisphp code: balrog - note that (), [], and {} are interchangeable

You'll notice that Lisphp does not come with any documentation other than what is on the Github page. A list of all the functions is in the Environment.php file. Here are brief descriptions of what some of the functions do:

define - defines a function or global variable

let - sets local variables

let* - sets local variables - the definitions can refer to each other

setf! - sets a local variable in an "imperative" style: (setf! foo 5). For setting local variables, prefer let first, followed by let*, followed by setf!

lambda - creates an anonymous function

apply - applies a function to an array of arguments

list - creates a Lisphp list: (list) or (list 'a' 'b' 'c')

array - creates a PHP array: (array) or (array 'a' 'b' 'c')

do - executes code several times in a loop

car - returns the first item in a list: (car flavors)

cdr - returns the remaining items in the list (i.e., not the first one): (cdr flavors)

at - returns the value at the given key: (at flavors 'key')

set-at! - sets the value at the given key: (set-at! flavors 'key' 'value')

unset-at! - unsets the value at the given key: (unset-at! flavors 'key' 'value')

exists-at? - does isset() on the value at the given key: (exists-at? flavors 'key')

count - returns the number of items in the list: (count flavors)

map - applies a function to every item in a list

filter - filters out items from a list

fold - (aka "reduce") goes through a list to create a single value

if - if statement

cond - switch statement

= - ==

== - ===

!=, !==, <, >, <=, >=, +, -, /, *, %, not, and, or, nil, true, false

. - concatenates strings

isa? - returns whether the object is an instance of the given class: (isa? foo <ArrayObject>)

string - strval()

substring - substr()

string-upcase - strtoupper()

string-downcase - strtolower()

I'm not sure about the following - if you know, let me know:

eval

quote

symbol

macro

dict - I'm not exactly sure how this works. I made a replacement called "hash"—see below.

I also added the following custom functions - I'll give the code in my next blog post:

import: imports a lisp file: (import 'foo/bar/baz.php')

php: runs a PHP function without having to import it: (php :htmlentities 'foo')

environment: this is the Lisp environment itself added as a variable, to allow you to check if a function exists: (exists-at? environment 'my-function')

Finally, some tips:

See if your editor has a plugin that will automatically indent your Lisp code. For example, Sublime Text has a lispindent plugin that will indent your code whenever you press Enter; you can also press Command+I to re-indent the selected code.

Sometimes you may need to dive into the Lisphp code to fix things. This is a good opportunity to learn how Lisphp works, and to contribute back by submitting a pull requests. I submitted twopull requests and they were accepted immediately.

To import a constant: (use +XG_Model::PLAINTEXT+). Now you can reference +XG_Model::PLAINTEXT+.