44
55from django .conf import settings
66from django .core .management .base import BaseCommand
7+ from django .template import Context , Template
78from django .template .loaders .app_directories import get_app_template_dirs
89
910from dashboard .templatetags .bundle import render
1011
12+ from app .bundle_context import context , templateTags
1113
12- def rmdir (loc ):
14+
15+ def rmdir (loc , depth = 1 ):
1316 # drop both the bundled and the bundles before recreating
1417 if os .path .exists (loc ) and os .path .isdir (loc ):
15- print ('- Deleting assets from: %s' % loc )
16- shutil .rmtree (loc )
18+ # list all dirs/paths in the loc
19+ files = os .listdir (loc )
20+
21+ print ('%s Deleting %s assets from: %s' % ('-' * depth , len (files ), loc ))
1722
23+ # delete files/dirs from the given loc leaving the loc dir intact
24+ for path in files :
25+ nextLoc = os .path .join (loc , path )
26+ if os .path .isdir (nextLoc ):
27+ rmdir (nextLoc , depth + 1 )
28+ else :
29+ os .remove (nextLoc )
1830
1931def rmdirs (loc , kind ):
2032 # base path of the assets
@@ -29,6 +41,11 @@ class Command(BaseCommand):
2941 help = 'generates .js/.scss files from bundle template tags'
3042
3143 def handle (self , * args , ** options ):
44+ """ This command will collect templates, render them with the bundleContext and run them through the bundle procedure"""
45+
46+ print ('\n Collect template files from all apps:' )
47+
48+ # get a list of all templates (rather than views to avoid segfault error that django-compressor was giving us on production)
3249 template_dir_list = []
3350 for template_dir in get_app_template_dirs ('templates' ):
3451 if settings .BASE_DIR in template_dir :
@@ -41,29 +58,38 @@ def handle(self, *args, **options):
4158 if ".html" in filename :
4259 template_list .append (os .path .join (base_dir , filename ))
4360
61+ print ('\n - %s templates discovered' % len (template_list ))
62+
4463 # using regex to grab the bundle tags content from html
4564 block_pattern = re .compile (r'({%\sbundle(.|\n)*?(?<={%\sendbundle\s%}))' )
4665 open_pattern = re .compile (r'({%\s+bundle\s+(js|css|merge_js|merge_css)\s+?(file)?\s+?([^\s]*)?\s+?%})' )
4766 close_pattern = re .compile (r'({%\sendbundle\s%})' )
48- static_open_pattern = re . compile ( r'({%\sstatic\s["|\'])' )
49- static_close_pattern = re . compile ( r'(\s?%}(\"|\')?\s?\/?>) ' )
67+
68+ print ( ' \n Clear bundle directories: \n ' )
5069
5170 # remove the previously bundled files
5271 for ext in ['js' , 'scss' , 'css' ]:
5372 rmdirs ('assets' , ext )
5473 rmdirs ('static' , ext )
5574
56- print ('\n Start generating bundle files \n ' )
75+ print ('\n Start generating bundled assets (using app.bundleContext as context): \n ' )
5776
5877 # store unique entries for count
5978 rendered = dict ()
6079
80+ # get the tags and context from bundleContext
81+ tags = templateTags ()
82+ bundleContext = context ()
83+ # load the bundleContext into a Context instance so that it can be fed to Template.render
84+ bundleContext = Context (bundleContext )
85+
86+ # check every template for bundle tags
6187 for template in template_list :
6288 try :
63- f = open (( '%s' % template ). replace ( '/' , os . sep ), 'r' , encoding = 'utf8' )
64-
65- t = f . read ()
66- if re .search (block_pattern , t ) is not None :
89+ # read the template file
90+ t = open (( '%s' % template ). replace ( '/' , os . sep ), 'r' , encoding = 'utf8' ). read ()
91+ # check for bundle tags
92+ if re .search (block_pattern , t ):
6793 for m in re .finditer (block_pattern , t ):
6894 block = m .group (0 )
6995 details = re .search (open_pattern , block )
@@ -76,15 +102,22 @@ def handle(self, *args, **options):
76102 block = re .sub (open_pattern , '' , block )
77103 block = re .sub (close_pattern , '' , block )
78104
79- # clean static helper if we havent ran this through parse
80- block = re .sub (static_open_pattern , '' , block )
81- block = re .sub (static_close_pattern , '>' , block )
105+ # add static helper to the block
106+ block = '{% ' + 'load %s' % ' ' .join (tags ) + ' %}\n ' + block
107+
108+ # create a template from the block
109+ block = Template (block )
110+
111+ # render the template with bundleContext
112+ block = block .render (bundleContext )
113+
114+ # clean static_url from the path (its not required but is included as legacy in most script/link inclusions)
115+ block = block .replace (settings .STATIC_URL , "" )
82116
83117 # render the template (producing a bundle file)
84118 rendered [render (block , kind , 'file' , name , True )] = True
85-
86119 except Exception as e :
87120 print ('-- X - failed to parse %s: %s' % (template , e ))
88121 pass
89122
90- print ('\n Generated %s bundle files ' % len (rendered ))
123+ print ('\n \n ------------------- Generated %s bundled assets ------------------- \n \n ' % len (rendered ))
0 commit comments