Sunday, July 08


Speaking In Minx (1.2)

I mentioned in my previous post that Minx 1.2 has involved a major overhaul of the templating system, so that it now provides multiple methods for accessing your data.  You may have missed this, because that post was mostly user interface port, so here's how that works, using a single example: Show me the title and author of the last 20 posts published on my blog.


Meta is the template language you know and love, and so far has been the main interface for anything you wanted to do.  It's a good thing it makes this easy!

[posts count=20]
[post.title] | []<br/>

By default the [posts] method lists your posts in descending date order (i.e. most recent first), and hides anything unpublished, so you don't need to specify any options for that.


Lua is the scripting language and main template engine in Minx 1.2.  You can fall back to a 1.1-style interpreted template if you really need to (and there is one semantic difference between old and new templates that might make this necessary for perfect compatibility), but by default, templates are compiled from Meta into Lua when you create them, and from Lua to native machine code when they run.

This is what that template would look like* in Lua:

for post in api.posts{count=20} do
  print(post.title, ' | ',, '<br/>')

The one trick there is that the posts function is called with curly brackets {} to pass it a table, instead of round brackets () for a regular parameter list.  That's syntactic sugar in Lua; you could also write it as 

for post in api.posts({count=20}) do

From Lua you simply print or write your content, and it is directed to the user's web browser.  Even if you've never done much programming, it's pretty easy to get started.



In fact, you could leave out the fields list and it would give you everything, but this way there's less data to download and parse, which is good for everyone.

The second format displays the function of an API you're already using without being aware of it: URL selectors.  Your blog archives, where you specify to get posts from May 2012: That's an URL selector.  There's no actual archive folder; it's all handled dynamically.  URL selectors have been greatly extended in 1.2, with a couple of dozen new parameters for filtering, searching, and sorting content.

These calls will return the data in JSON format, rather than the exact layout produced by the various templates.  This will be addressed in a future release with plugin formatters, but for now, JSON rules.**


This is the way I code to the new API, and I plan to make this available on an experimental basis in 1.2.  

There are two ways to use the Python API: As a wrapper around the REST API, or as Python modules for inclusion in standalone Minx installs.  (You can't install your own Python modules in the core system, for obvious reasons, but I plan to offer virtual Minxes for those who'd like to develop applications in this way.)

The Python API is essentially identical either way, and very similar to Lua:

for post in api.posts(count=20):
  print(post.title, ' | ',, '<br/>')

Technically, Python doesn't require the brackets on print yet, but it will in the future, and they make the code more similar to Lua, so it's a good idea to include them.


This is under development; it seems to work, but I'm not sure yet whether it will be robust enough for release in 1.2.  As with Python, it will be available as a wrapper for the REST API, and also for direct modules using RubyPython.

Ruby code is a little different to Python or Lua, partly because it has a more thoroughly generalised object model.  But it's not hard once you get used to it.

api.posts.each({:count => 20}) | post |
  print(post.title, ' | ',, '<br/>')

As with Python, the brackets on print are optional.

The advantage of Ruby is that it allows Ruby programmers to work with a familiar language and familiar libraries while building on the Minx framework - and integrating with Ruby also allows Minx access to Ruby libraries that don't have direct Python equivalents.

Anyway, that's a very quick rundown on the new APIs in 1.2; the full API reference, when it lands, will run to several thousand pages.  I'm not typing all of that, though! It's automatically generated using Sphinx from the data model and its documentation, so that every method is documented for every version of the API, and every example is equivalent on each API as well.

The tutorials and user guide will be mostly hand-crafted*** but the new reference will automatically document absolutely everything.

* Right now, what the compiler produces is this:

for post in api.posts{count=20} do
  write(" | ")

Which is correct (and neatly indented) but a bit mechanical.  But most users won't ever look at that code, so for now I'm happy with correctness; idiomaticness can follow.

Update: Ta-da! Added support for merged writes:

for post in api.posts{count=20} do
  write(post.title, " | ",, "<br/>\n")

I need to add some more intelligence there to keep long sections of text readable, but it certainly works nicely for short examples.

** I'm so glad that XML APIs are a dying breed.  They were an improvement on some of the binary APIs I had to work with in the bad old days, but still horrible in their own way.

*** And illustrated.

Posted by: Pixy Misa at 03:40 PM | Comments (2) | Add Comment | Trackbacks (Suck)
Post contains 931 words, total size 9 kb.

My E-mail was hacked...don't open ANY E-Mails you got from me July 9th.

Sorry for the OT comment.

Posted by: The Brickmuppet at Tuesday, July 10 2012 11:18 AM (e9h6K)

2 No worries. wink

Saw an email, then checked your blog to see if you knew.  

Posted by: Pixy Misa at Tuesday, July 10 2012 11:39 AM (PiXy!)

Hide Comments | Add Comment

Comments are disabled. Post is locked.
53kb generated in CPU 0.0124, elapsed 0.1022 seconds.
56 queries taking 0.0935 seconds, 342 records returned.
Powered by Minx 1.1.6c-pink.