Skip to content

Markup Language featuring html outlining via css-selectors, embedded python, and extensibility.

License

Notifications You must be signed in to change notification settings

micheltem/dmsl

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This project is a work in progress. Refer to dmsl/test/templates/ for additional syntax not covered here.

Follow development at http://github.com/dasacc22/dmsl or view this readme at http://damsel.dasa.cc

.. _build:

Building From Source
=====================
dmsl depends on Cython >= 0.13 and lxml so install as per your distribution, for example

.. sourcecode:: bash
  
  sudo apt-get install python-lxml; sudo easy_install cython

After satisfying lxml and cython dependencies, clone the repo from github, build and install globally with the following

.. sourcecode:: bash
  
  git clone git://github.com/dasacc22/dmsl.git
  cd dmsl
  sudo python setup.py install

or if you wish to not install globally, you can build the C extensions in place
and use from directory

.. sourcecode:: bash
  
  python setup.py build_ext -i

.. _unittests:

Running Unit Tests
==================
To run unit tests, build in place and execute test/ directory:

.. sourcecode:: bash

  python setup.py build_ext -i
  cd dmsl/
  python test/

.. _featuresexamples:

Features and Examples
=====================
Damsel can run via command line:

.. sourcecode:: bash

  python -m dmsl -h  # see for more info

To use in source:

.. sourcecode:: python

  import dmsl
  dmsl.set_template_dir('./templates')
  dmsl.Template('index.dmsl').render({'content': 'Hello World'})

Damsel features html outlining similar to css selectors. The most notable difference is using a percent (%) to specify a regular tag.

.. sourcecode:: haml
  
  %html
      %body Hello World

Damsel is indention based, but works just fine with variable indention with a minimum of two spaces and as long as blocks align as intended.

.. sourcecode:: haml
  
  %html
    %body
          %p This works just fine

Tags can also be inlined if they are only wrappers.

.. sourcecode:: haml
  
  %html %body %ul
      %li %span Home
      %li %span Page

Classes and IDs can be specified the same as CSS. If no tag is specified, a DIV is created by default.

.. sourcecode:: haml
  
  %html %body
      #top %h1.title Hello World
      #content %p.text

Attributes are specified as in CSS. Breaking attributes across multiple lines is not yet implemented.

.. sourcecode:: haml
  
  %html %body
      %img[border=0][style="margin: 20px;"]
      %a#home.link[href="http://www.dasa.cc"]

Damsel also supports embedding python in the document. There's no special syntax for use aside from embedding a function call inline of a tag, starting the call with a colon (:). HTML outlining and python can be intermixed for different effect. Embedding a variable within an outline element is done via the standard python string `Formatter <http://docs.python.org/library/string.html#format-string-syntax>`_.

.. sourcecode:: haml
  
  n = 4
  greet = lambda x: 'Hello, '+x
  %html %body for x in range(n):
      y = x*2
      %p Number is {x}. :greet('Daniel'). Here's the number doubled, {y}

Python can be used to control the flow of the document as well

.. sourcecode:: haml
  
  val = False
  %html %body
      %p Test the value of val
      if val:
          %p val is True
      else:
          %p val is False

It's important to note how the document becomes aligned. Intermixed outline elements will be left-aligned to their nearest python counterpart. So above, %p val is False will be the resulting object, and will be properly aligned where the if statement is, placing it as a node of body.

The evaluation of python code takes place in a sandbox that can be extended with custom objects and functions. So for example, in your controller code:

.. sourcecode:: python
  
  import pymongo.objectid
  import dmsl
  dmsl.extensions['ObjectId'] = pymongo.objectid.ObjectId

ObjectId will then be available for use in your dmsl templates.

Another extensible feature of dmsl are filters. A filter allows you to write a slightly altered syntax for calling a python function. Take for example the builtin js filter used for specifying multiple javascript files in a particular location

.. sourcecode:: python
  
  def js(s, _locals):
      s = s.splitlines()
      n = s[0]
      s = s[1:]
      return ['%script[src={0}{1}][type="text/javascript"]'.format(n, x) for x in s]

In a dmsl template, this (as other filters) can be accessed like so

.. sourcecode:: haml
  
  %html %head
      :js /js/lib/
          jquery.min.js
          jquery.defaultinput.js
          utils.js
          js.js

This would be the same as explicitly typing it out

.. sourcecode:: haml
  
  %html %head
      %script[src="/js/lib/jquery.min.js"][type="text/javascript"]
      %script[src="/js/lib/jquery.defaultinput.js"][type="text/javascript"]
      %script[src="/js/lib/utils.js"][type="text/javascript"]
      %script[src="/js/lib/js.js"][type="text/javascript"]

Filters can be used for most anything from a docutils or markdown processor to whatever you might imagine.

Being able to create templates are a must and there are two methods implemented in dmsl to do so. The first is the standard include statement. Consider the following file, top.dmsl

.. sourcecode:: haml
  
  #top
      %h1 Hello World
      %p.desc This is a test.

This file can then be included into another, for example, overlay.dmsl

.. sourcecode:: haml
  
  %html %body
      include('top.dmsl')
      #content
          %p One
          %p Two

The top.dmsl contents will be aligned appropriately based upon its location in overlay.dmsl. The second method for creating a proper template is the ability to extend a dmsl template. This is handled by a call to the extends function, and then specifying which portion of the template we want to extend. Specifying which portion to extend is based on the ID assigned to a tag. Take the overlay.dmsl example from above. There are two elements we can extend, #top and #content. We can either override the contents, or append new elements to them. Let's do this in index.dmsl

.. sourcecode:: haml
  
  extends('overlay.dmsl')
  
  #top %h1 This will override all elements in top
  #content[super=]
      %p three

Here, we simply specify the the tag hash we want to access and then provide the nested content. If a super attribute is specified, this tells dmsl to append the content to the current element we're extending. This super attribute will **not** be a part of the final output. This method also forces strict conformance to a single ID per element, so if you're use to given multiple nodes the exact same ID, now is a good time to stop.

More examples coming soon, refer to test/templates for more.

About

Markup Language featuring html outlining via css-selectors, embedded python, and extensibility.

Resources

License

Stars

Watchers

Forks

Packages

No packages published