We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
overextends tag broken in Django 1.7+1.8
Looks like the changes made to `loader_tags.py` in a50de50699bb6a24bfb5f118449991aa7608b426 either didn't work or both Django versions have since changed.

As reported here: https://groups.google.com/d/msg/mezzanine-users/_QWfFVB3RVc/ZirizEV9t2YJ

Just pinging @AlexHill as you might have a head's up on this one already. 

I made a quick attempt by changing `find_template_loader = context.engine.find_template_loader` to `find_template_loader = context.engine.find_template_loader` which appears to work for 1.8, but then other possibly unrelated exceptions came up.

BTW my quick tip for actually running `overextends` is to modify the first line of `core/templates/admin/base_site.html` to use it instead of `extends`


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mezzanine/template/loader_tags.py`
Content:
```
1 from __future__ import unicode_literals
2 from future.builtins import map
3 
4 import os
5 
6 from django.template import Template, TemplateSyntaxError, TemplateDoesNotExist
7 from django.template.loader_tags import ExtendsNode
8 
9 from mezzanine import template
10 
11 
12 register = template.Library()
13 
14 
15 class OverExtendsNode(ExtendsNode):
16     """
17     Allows the template ``foo/bar.html`` to extend ``foo/bar.html``,
18     given that there is another version of it that can be loaded. This
19     allows templates to be created in a project that extend their app
20     template counterparts, or even app templates that extend other app
21     templates with the same relative name/path.
22 
23     We use our own version of ``find_template``, that uses an explict
24     list of template directories to search for the template, based on
25     the directories that the known template loaders
26     (``app_directories`` and ``filesystem``) use. This list gets stored
27     in the template context, and each time a template is found, its
28     absolute path gets removed from the list, so that subsequent
29     searches for the same relative name/path can find parent templates
30     in other directories, which allows circular inheritance to occur.
31 
32     Django's ``app_directories``, ``filesystem``, and ``cached``
33     loaders are supported. The ``eggs`` loader, and any loader that
34     implements ``load_template_source`` with a source string returned,
35     should also theoretically work.
36     """
37 
38     def find_template(self, name, context, peeking=False):
39         """
40         Replacement for Django's ``find_template`` that uses the current
41         template context to keep track of which template directories it
42         has used when finding a template. This allows multiple templates
43         with the same relative name/path to be discovered, so that
44         circular template inheritance can occur.
45         """
46 
47         # These imports want settings, which aren't available when this
48         # module is imported to ``add_to_builtins``, so do them here.
49         import django.template.loaders.app_directories as app_directories
50         try:
51             # Django >= 1.8
52             app_template_dirs = app_directories.get_app_template_dirs
53         except AttributeError:
54             # Django <= 1.7
55             app_template_dirs = app_directories.app_template_dirs
56 
57         try:
58             # Django >= 1.8
59             find_template_loader = context.engine.find_template_loader
60         except AttributeError:
61             # Django <= 1.7
62             from django.template.loaders import find_template_loader
63 
64         from mezzanine.conf import settings
65 
66         # Store a dictionary in the template context mapping template
67         # names to the lists of template directories available to
68         # search for that template. Each time a template is loaded, its
69         # origin directory is removed from its directories list.
70         context_name = "OVEREXTENDS_DIRS"
71         if context_name not in context:
72             context[context_name] = {}
73         if name not in context[context_name]:
74             all_dirs = list(settings.TEMPLATE_DIRS) + list(app_template_dirs)
75             # os.path.abspath is needed under uWSGI, and also ensures we
76             # have consistent path separators across different OSes.
77             context[context_name][name] = list(map(os.path.abspath, all_dirs))
78 
79         # Build a list of template loaders to use. For loaders that wrap
80         # other loaders like the ``cached`` template loader, unwind its
81         # internal loaders and add those instead.
82         loaders = []
83         for loader_name in settings.TEMPLATE_LOADERS:
84             loader = find_template_loader(loader_name)
85             loaders.extend(getattr(loader, "loaders", [loader]))
86 
87         # Go through the loaders and try to find the template. When
88         # found, removed its absolute path from the context dict so
89         # that it won't be used again when the same relative name/path
90         # is requested.
91         for loader in loaders:
92             dirs = context[context_name][name]
93             try:
94                 source, path = loader.load_template_source(name, dirs)
95             except TemplateDoesNotExist:
96                 pass
97             else:
98                 # Only remove the absolute path for the initial call in
99                 # get_parent, and not when we're peeking during the
100                 # second call.
101                 if not peeking:
102                     remove_path = os.path.abspath(path[:-len(name) - 1])
103                     context[context_name][name].remove(remove_path)
104                 return Template(source)
105         raise TemplateDoesNotExist(name)
106 
107     def get_parent(self, context):
108         """
109         Load the parent template using our own ``find_template``, which
110         will cause its absolute path to not be used again. Then peek at
111         the first node, and if its parent arg is the same as the
112         current parent arg, we know circular inheritance is going to
113         occur, in which case we try and find the template again, with
114         the absolute directory removed from the search list.
115         """
116         parent = self.parent_name.resolve(context)
117         # If parent is a template object, just return it.
118         if hasattr(parent, "render"):
119             return parent
120         template = self.find_template(parent, context)
121         for node in template.nodelist:
122             if (isinstance(node, ExtendsNode) and
123                     node.parent_name.resolve(context) == parent):
124                 return self.find_template(parent, context, peeking=True)
125         return template
126 
127 
128 @register.tag
129 def overextends(parser, token):
130     """
131     Extended version of Django's ``extends`` tag that allows circular
132     inheritance to occur, eg a template can both be overridden and
133     extended at once.
134     """
135     bits = token.split_contents()
136     if len(bits) != 2:
137         raise TemplateSyntaxError("'%s' takes one argument" % bits[0])
138     parent_name = parser.compile_filter(bits[1])
139     nodelist = parser.parse()
140     if nodelist.get_nodes_by_type(ExtendsNode):
141         raise TemplateSyntaxError("'%s' cannot appear more than once "
142                                   "in the same template" % bits[0])
143     return OverExtendsNode(nodelist, parent_name, None)
144
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mezzanine/template/loader_tags.py b/mezzanine/template/loader_tags.py
--- a/mezzanine/template/loader_tags.py
+++ b/mezzanine/template/loader_tags.py
@@ -49,17 +49,18 @@
         import django.template.loaders.app_directories as app_directories
         try:
             # Django >= 1.8
-            app_template_dirs = app_directories.get_app_template_dirs
+            get_app_template_dirs = app_directories.get_app_template_dirs
+            app_template_dirs = get_app_template_dirs('templates')
         except AttributeError:
             # Django <= 1.7
             app_template_dirs = app_directories.app_template_dirs
 
         try:
             # Django >= 1.8
-            find_template_loader = context.engine.find_template_loader
+            find_template_loader = context.template.engine.find_template_loader
         except AttributeError:
             # Django <= 1.7
-            from django.template.loaders import find_template_loader
+            from django.template.loader import find_template_loader
 
         from mezzanine.conf import settings

{"golden_diff": "diff --git a/mezzanine/template/loader_tags.py b/mezzanine/template/loader_tags.py\n--- a/mezzanine/template/loader_tags.py\n+++ b/mezzanine/template/loader_tags.py\n@@ -49,17 +49,18 @@\n         import django.template.loaders.app_directories as app_directories\n         try:\n             # Django >= 1.8\n-            app_template_dirs = app_directories.get_app_template_dirs\n+            get_app_template_dirs = app_directories.get_app_template_dirs\n+            app_template_dirs = get_app_template_dirs('templates')\n         except AttributeError:\n             # Django <= 1.7\n             app_template_dirs = app_directories.app_template_dirs\n \n         try:\n             # Django >= 1.8\n-            find_template_loader = context.engine.find_template_loader\n+            find_template_loader = context.template.engine.find_template_loader\n         except AttributeError:\n             # Django <= 1.7\n-            from django.template.loaders import find_template_loader\n+            from django.template.loader import find_template_loader\n \n         from mezzanine.conf import settings\n", "issue": "overextends tag broken in Django 1.7+1.8\nLooks like the changes made to `loader_tags.py` in a50de50699bb6a24bfb5f118449991aa7608b426 either didn't work or both Django versions have since changed.\n\nAs reported here: https://groups.google.com/d/msg/mezzanine-users/_QWfFVB3RVc/ZirizEV9t2YJ\n\nJust pinging @AlexHill as you might have a head's up on this one already. \n\nI made a quick attempt by changing `find_template_loader = context.engine.find_template_loader` to `find_template_loader = context.engine.find_template_loader` which appears to work for 1.8, but then other possibly unrelated exceptions came up.\n\nBTW my quick tip for actually running `overextends` is to modify the first line of `core/templates/admin/base_site.html` to use it instead of `extends`\n\n", "before_files": [{"content": "from __future__ import unicode_literals\nfrom future.builtins import map\n\nimport os\n\nfrom django.template import Template, TemplateSyntaxError, TemplateDoesNotExist\nfrom django.template.loader_tags import ExtendsNode\n\nfrom mezzanine import template\n\n\nregister = template.Library()\n\n\nclass OverExtendsNode(ExtendsNode):\n    \"\"\"\n    Allows the template ``foo/bar.html`` to extend ``foo/bar.html``,\n    given that there is another version of it that can be loaded. This\n    allows templates to be created in a project that extend their app\n    template counterparts, or even app templates that extend other app\n    templates with the same relative name/path.\n\n    We use our own version of ``find_template``, that uses an explict\n    list of template directories to search for the template, based on\n    the directories that the known template loaders\n    (``app_directories`` and ``filesystem``) use. This list gets stored\n    in the template context, and each time a template is found, its\n    absolute path gets removed from the list, so that subsequent\n    searches for the same relative name/path can find parent templates\n    in other directories, which allows circular inheritance to occur.\n\n    Django's ``app_directories``, ``filesystem``, and ``cached``\n    loaders are supported. The ``eggs`` loader, and any loader that\n    implements ``load_template_source`` with a source string returned,\n    should also theoretically work.\n    \"\"\"\n\n    def find_template(self, name, context, peeking=False):\n        \"\"\"\n        Replacement for Django's ``find_template`` that uses the current\n        template context to keep track of which template directories it\n        has used when finding a template. This allows multiple templates\n        with the same relative name/path to be discovered, so that\n        circular template inheritance can occur.\n        \"\"\"\n\n        # These imports want settings, which aren't available when this\n        # module is imported to ``add_to_builtins``, so do them here.\n        import django.template.loaders.app_directories as app_directories\n        try:\n            # Django >= 1.8\n            app_template_dirs = app_directories.get_app_template_dirs\n        except AttributeError:\n            # Django <= 1.7\n            app_template_dirs = app_directories.app_template_dirs\n\n        try:\n            # Django >= 1.8\n            find_template_loader = context.engine.find_template_loader\n        except AttributeError:\n            # Django <= 1.7\n            from django.template.loaders import find_template_loader\n\n        from mezzanine.conf import settings\n\n        # Store a dictionary in the template context mapping template\n        # names to the lists of template directories available to\n        # search for that template. Each time a template is loaded, its\n        # origin directory is removed from its directories list.\n        context_name = \"OVEREXTENDS_DIRS\"\n        if context_name not in context:\n            context[context_name] = {}\n        if name not in context[context_name]:\n            all_dirs = list(settings.TEMPLATE_DIRS) + list(app_template_dirs)\n            # os.path.abspath is needed under uWSGI, and also ensures we\n            # have consistent path separators across different OSes.\n            context[context_name][name] = list(map(os.path.abspath, all_dirs))\n\n        # Build a list of template loaders to use. For loaders that wrap\n        # other loaders like the ``cached`` template loader, unwind its\n        # internal loaders and add those instead.\n        loaders = []\n        for loader_name in settings.TEMPLATE_LOADERS:\n            loader = find_template_loader(loader_name)\n            loaders.extend(getattr(loader, \"loaders\", [loader]))\n\n        # Go through the loaders and try to find the template. When\n        # found, removed its absolute path from the context dict so\n        # that it won't be used again when the same relative name/path\n        # is requested.\n        for loader in loaders:\n            dirs = context[context_name][name]\n            try:\n                source, path = loader.load_template_source(name, dirs)\n            except TemplateDoesNotExist:\n                pass\n            else:\n                # Only remove the absolute path for the initial call in\n                # get_parent, and not when we're peeking during the\n                # second call.\n                if not peeking:\n                    remove_path = os.path.abspath(path[:-len(name) - 1])\n                    context[context_name][name].remove(remove_path)\n                return Template(source)\n        raise TemplateDoesNotExist(name)\n\n    def get_parent(self, context):\n        \"\"\"\n        Load the parent template using our own ``find_template``, which\n        will cause its absolute path to not be used again. Then peek at\n        the first node, and if its parent arg is the same as the\n        current parent arg, we know circular inheritance is going to\n        occur, in which case we try and find the template again, with\n        the absolute directory removed from the search list.\n        \"\"\"\n        parent = self.parent_name.resolve(context)\n        # If parent is a template object, just return it.\n        if hasattr(parent, \"render\"):\n            return parent\n        template = self.find_template(parent, context)\n        for node in template.nodelist:\n            if (isinstance(node, ExtendsNode) and\n                    node.parent_name.resolve(context) == parent):\n                return self.find_template(parent, context, peeking=True)\n        return template\n\n\n@register.tag\ndef overextends(parser, token):\n    \"\"\"\n    Extended version of Django's ``extends`` tag that allows circular\n    inheritance to occur, eg a template can both be overridden and\n    extended at once.\n    \"\"\"\n    bits = token.split_contents()\n    if len(bits) != 2:\n        raise TemplateSyntaxError(\"'%s' takes one argument\" % bits[0])\n    parent_name = parser.compile_filter(bits[1])\n    nodelist = parser.parse()\n    if nodelist.get_nodes_by_type(ExtendsNode):\n        raise TemplateSyntaxError(\"'%s' cannot appear more than once \"\n                                  \"in the same template\" % bits[0])\n    return OverExtendsNode(nodelist, parent_name, None)\n", "path": "mezzanine/template/loader_tags.py"}], "after_files": [{"content": "from __future__ import unicode_literals\nfrom future.builtins import map\n\nimport os\n\nfrom django.template import Template, TemplateSyntaxError, TemplateDoesNotExist\nfrom django.template.loader_tags import ExtendsNode\n\nfrom mezzanine import template\n\n\nregister = template.Library()\n\n\nclass OverExtendsNode(ExtendsNode):\n    \"\"\"\n    Allows the template ``foo/bar.html`` to extend ``foo/bar.html``,\n    given that there is another version of it that can be loaded. This\n    allows templates to be created in a project that extend their app\n    template counterparts, or even app templates that extend other app\n    templates with the same relative name/path.\n\n    We use our own version of ``find_template``, that uses an explict\n    list of template directories to search for the template, based on\n    the directories that the known template loaders\n    (``app_directories`` and ``filesystem``) use. This list gets stored\n    in the template context, and each time a template is found, its\n    absolute path gets removed from the list, so that subsequent\n    searches for the same relative name/path can find parent templates\n    in other directories, which allows circular inheritance to occur.\n\n    Django's ``app_directories``, ``filesystem``, and ``cached``\n    loaders are supported. The ``eggs`` loader, and any loader that\n    implements ``load_template_source`` with a source string returned,\n    should also theoretically work.\n    \"\"\"\n\n    def find_template(self, name, context, peeking=False):\n        \"\"\"\n        Replacement for Django's ``find_template`` that uses the current\n        template context to keep track of which template directories it\n        has used when finding a template. This allows multiple templates\n        with the same relative name/path to be discovered, so that\n        circular template inheritance can occur.\n        \"\"\"\n\n        # These imports want settings, which aren't available when this\n        # module is imported to ``add_to_builtins``, so do them here.\n        import django.template.loaders.app_directories as app_directories\n        try:\n            # Django >= 1.8\n            get_app_template_dirs = app_directories.get_app_template_dirs\n            app_template_dirs = get_app_template_dirs('templates')\n        except AttributeError:\n            # Django <= 1.7\n            app_template_dirs = app_directories.app_template_dirs\n\n        try:\n            # Django >= 1.8\n            find_template_loader = context.template.engine.find_template_loader\n        except AttributeError:\n            # Django <= 1.7\n            from django.template.loader import find_template_loader\n\n        from mezzanine.conf import settings\n\n        # Store a dictionary in the template context mapping template\n        # names to the lists of template directories available to\n        # search for that template. Each time a template is loaded, its\n        # origin directory is removed from its directories list.\n        context_name = \"OVEREXTENDS_DIRS\"\n        if context_name not in context:\n            context[context_name] = {}\n        if name not in context[context_name]:\n            all_dirs = list(settings.TEMPLATE_DIRS) + list(app_template_dirs)\n            # os.path.abspath is needed under uWSGI, and also ensures we\n            # have consistent path separators across different OSes.\n            context[context_name][name] = list(map(os.path.abspath, all_dirs))\n\n        # Build a list of template loaders to use. For loaders that wrap\n        # other loaders like the ``cached`` template loader, unwind its\n        # internal loaders and add those instead.\n        loaders = []\n        for loader_name in settings.TEMPLATE_LOADERS:\n            loader = find_template_loader(loader_name)\n            loaders.extend(getattr(loader, \"loaders\", [loader]))\n\n        # Go through the loaders and try to find the template. When\n        # found, removed its absolute path from the context dict so\n        # that it won't be used again when the same relative name/path\n        # is requested.\n        for loader in loaders:\n            dirs = context[context_name][name]\n            try:\n                source, path = loader.load_template_source(name, dirs)\n            except TemplateDoesNotExist:\n                pass\n            else:\n                # Only remove the absolute path for the initial call in\n                # get_parent, and not when we're peeking during the\n                # second call.\n                if not peeking:\n                    remove_path = os.path.abspath(path[:-len(name) - 1])\n                    context[context_name][name].remove(remove_path)\n                return Template(source)\n        raise TemplateDoesNotExist(name)\n\n    def get_parent(self, context):\n        \"\"\"\n        Load the parent template using our own ``find_template``, which\n        will cause its absolute path to not be used again. Then peek at\n        the first node, and if its parent arg is the same as the\n        current parent arg, we know circular inheritance is going to\n        occur, in which case we try and find the template again, with\n        the absolute directory removed from the search list.\n        \"\"\"\n        parent = self.parent_name.resolve(context)\n        # If parent is a template object, just return it.\n        if hasattr(parent, \"render\"):\n            return parent\n        template = self.find_template(parent, context)\n        for node in template.nodelist:\n            if (isinstance(node, ExtendsNode) and\n                    node.parent_name.resolve(context) == parent):\n                return self.find_template(parent, context, peeking=True)\n        return template\n\n\n@register.tag\ndef overextends(parser, token):\n    \"\"\"\n    Extended version of Django's ``extends`` tag that allows circular\n    inheritance to occur, eg a template can both be overridden and\n    extended at once.\n    \"\"\"\n    bits = token.split_contents()\n    if len(bits) != 2:\n        raise TemplateSyntaxError(\"'%s' takes one argument\" % bits[0])\n    parent_name = parser.compile_filter(bits[1])\n    nodelist = parser.parse()\n    if nodelist.get_nodes_by_type(ExtendsNode):\n        raise TemplateSyntaxError(\"'%s' cannot appear more than once \"\n                                  \"in the same template\" % bits[0])\n    return OverExtendsNode(nodelist, parent_name, None)\n", "path": "mezzanine/template/loader_tags.py"}]}