Commits

Carlos Daniel Ruvalcaba Valenzuela committed 42b2125

Added jinja extension to compile LESS from templates

Comments (0)

Files changed (3)

 
         return app
 
+
+Jinja2 Extension
+----------------------------------
+
+tgext.less provides and extension for jinja2 templates to compile LESS embedded directly on your templates,
+to activate it just add it to your config/app_config.py file the following::
+
+    from tgext.less.jinja import LessExtension
+
+    base_config.jinja_extensions = [LessExtension]
+
+Now you can use the less tag in your templates::
+
+    <style type="text/css">
+    {% less "main" %}
+    #header {
+        h1 {
+            font-size: 24pt;
+        }
+    }
+    {% endless %}
+    </style>
+
+Where "main" is a unique identifier for that LESS section.
+
+You should take into account that when using mixins or any other identifier not defined inside the
+tag the LESS code will fail to compile, you can use the @import statement to include a file, in which
+case you should include the path relative to your static file directory.
+
+You should be aware that when using this extension with the LESS import statement the output can get
+big quickly as the compiler currently does not just get the necessary things from the imported file but
+it just naively includes the whole file.
 from setuptools import setup, find_packages
 import sys, os
 
-version = '0.2'
+version = '0.3'
 
 here = os.path.abspath(os.path.dirname(__file__))
 try:
         "Topic :: Software Development :: Libraries :: Python Modules",
         "Framework :: TurboGears"
         ],
-      keywords='turbogears2.extension LESS WSGI',
+      keywords='turbogears2.extension LESS WSGI jinja2.extension',
       author='Carlos Daniel Ruvalcaba Valenzuela',
       author_email='clsdaniel@gmail.com',
       url='http://bitbucket.org/clsdaniel/tgext.less',
+import subprocess
+import os
+from tg import config
+from jinja2 import nodes
+from jinja2.ext import Extension
+
+class LessExtension(Extension):
+    tags = set(['less'])
+    
+    def __init__(self, environment):
+        super(LessExtension, self).__init__(environment)
+        self.static_files_path = os.path.abspath(config['pylons.paths']['static_files'])
+
+    def compile_less(self, name, caller):
+        less_body = caller()
+
+        # We are assuming Jinja only calls this function when the template
+        # is loaded or reloaded (cached), thus no caching on our part.
+        lessc = subprocess.Popen(['lessc', "-x", "-I" + self.static_files_path, '-'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
+
+        # TODO: EOF Character is not crossplatform, 125 works for linux need to find what works for windows (probably 26)
+        out, err = lessc.communicate(input=less_body+chr(125))
+
+        # TODO: Handle returned error code from compiler
+        if err:
+            return ""
+
+        return out
+
+    def parse(self, parser):
+        lineno = parser.stream.next().lineno
+        args = [parser.parse_expression()]
+
+        less_body = parser.parse_statements(['name:endless'], drop_needle=True)
+
+        return nodes.CallBlock(self.call_method('compile_less', args), [], [], less_body).set_lineno(lineno)
+