#!/usr/bin/env python import os import re import sys import json import itertools import collections def list_templates(): from django.template.loaders.app_directories import app_template_dirs res = [] for dirpath, dirs, fnames in itertools.chain(*(os.walk(path) for path in app_template_dirs)): for fname in fnames: if os.path.splitext(fname)[1] == '.html' and 'templates' in dirpath: filepath = os.path.join(dirpath, fname) res.append(os.path.join(filepath)) return res def search_file(filepath, regex): if filepath in exhausted_templates: return None with open(filepath) as f: for l in f: res = regex.search(l) if res: exhausted_templates.append(filepath) return res return None def find_children(path, template_name): reg = re.compile( r"""\{\%%\s*extends\s+[\'\"]%s[\'\"]\s*\%%\}""" % template_name) res = [] for filepath in templates: if search_file(filepath, reg): res.append(os.path.join(filepath)) return res def Tree(): return collections.defaultdict(Tree) if __name__ == '__main__': if len(sys.argv) < 2: print '''Example: DJANGO_SETTINGS_MODULE=mysite.settings %s base.html ''' % sys.argv[0] sys.exit(1) templates = list_templates() exhausted_templates = [] tree = Tree() template_reg = re.compile(r'^.*?/templates/') def fulfill(tree, template_name): template_name = template_reg.sub('', template_name) sub_tree = tree[template_name] for fname in find_children('.', template_name): fulfill(sub_tree, fname) top = sys.argv[1] fulfill(tree, top) print(json.dumps(tree, indent=4))