Jason Goldstein avatar Jason Goldstein committed e691d6f

Scaffolding for being able to insert extra variables into the start of a LESS file.

Comments (0)

Files changed (1)

less_is_more/templatetags/less_tags.py

 from django.conf import settings
 import os, subprocess
 from django.template import TemplateSyntaxError
+from django.core.files.storage import FileSystemStorage
+register = template.Library()
 
-register = template.Library()
+import time
 
 """
 For Windows, https://github.com/duncansmart/less.js-windows is awesome. But you need the exact path, so I'm not setting it in advanced.
 
 OUTPUT_NOISE = ['\x1b', '[39m', '[31m', '[90m'] # Output coloring
 
-# TemplateSyntaxError("LESS CSS compiler sent an angry error message about your file. Here's it's complaint:\n\n \x1b[31mParseError: Syntax Error on line 2\x1b[39m\x1b[31m in \x1b[39mC:\\Users\\Jason\\dev\\open_src\\less_is_more\\tests\\static\\invalid_style.less\x1b[90m:2:1\x1b[39m\n",)
-
 
 @register.simple_tag(takes_context=True)
-def less(context, less):
+def less(context, less, extra_variables={}):
     """
     Runs the LESS. It's smart.
 
 
     If LESS_TOOLS_SETTINGS['is_multitenant'] = True, we'll get static root off the request instead of settings.
 
+    You can pass extra variables to LESS as well. Do this very carefully. Here's how:
+
+    {
+        'last_updated': a_datetime,
+        'content': {
+            '@primaryColor':'blue',
+            '@mainFont': 'Arial, Helvetica, Sans-Serif',
+        }
+    }
+
+
     """
     
     # Configuration Details
     if not os.path.isfile(less_file):
         raise TemplateSyntaxError('%s is not a file, and you can\'t run the LESS compiler on it.' % less_file)
 
-    modified = str(os.path.getmtime(less_file))
+    modified = str(_get_modified_time(less_file, extra_variables.get('last_updated', False)))
 
     output = "%s%s.%s.css" % (LESS_TOOLS_SETTINGS['output_dir'], less.replace("/","."), modified) # Hash it for easy caching
 
     results = None # Nothing built
 
     if not os.path.isfile("%s%s" % (settings.MEDIA_ROOT, output)): # Create the file only if it hasn't been already
+        less_file = _get_jit_less_file(less_file, extra_variables)
         try:
             # Spin up a subprocess to generate the file
-            process = subprocess.check_output(['node', compiler, less_file, '%s%s' % (settings.MEDIA_ROOT, output), '-compress'], shell=use_shell, stderr=subprocess.STDOUT)
+            process = subprocess.check_output(['node', compiler, less_file, '%s%s' % 
+                (settings.MEDIA_ROOT, output), '-compress'], shell=use_shell, stderr=subprocess.STDOUT)
             results = True # Legal build
         except subprocess.CalledProcessError, err: # capture any errors
             results = err.output
 
     return "%s%s" % (settings.MEDIA_URL, output)
 
+
+def _get_modified_time(less_file, override_datetime):
+    """ Return whichever is latest: the modified date of the less file, or the 
+    overriding datetime that we think is the timestamp of... whenever our special
+    variables changed. """
+
+    extra_vars_modified = 0
+    if override_datetime:
+        extra_vars_modified = time.mktime(override_datetime.timetuple())
+    file_modified = os.path.getmtime(less_file)
+    return max(extra_vars_modified, file_modified)
+
+
+def _get_jit_less_file(less_file, extra_variables={}):
+    """ If we have extra variables, we're going to build a temporary file with them prepended and return that instead. """
+    if not 'content' in extra_variables: # First, if we don't have anything extra, just quit.
+        return less_file
+
+    extra_less = ""
+    for var in extra_variables['content']:
+        extra_less = "%(base)s\n%(key)s: %(value)s;" % {
+            'base': extra_less, 
+            'key': var,
+            'value': extra_variables['content'][var],
+            }
+
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.