diff --git a/djblets/extensions/extension.py b/djblets/extensions/extension.py
index 5573e09d5d600f8e9f8c20156ebd40819bbd24f6..872dec8f290ace78c75d6bfa174572f004117114 100644
--- a/djblets/extensions/extension.py
+++ b/djblets/extensions/extension.py
@@ -99,13 +99,17 @@ class JSExtension(object):
         """
         return self.apply_to is None or url_name in self.apply_to
 
-    def get_model_data(self):
+    def get_model_data(self, request, **kwargs):
         """Return model data for the Extension model instance in JavaScript.
 
         Subclasses can override this to return custom data to pass to
         the extension class defined in :js:attr:`model_class`. This data must
         be JSON-serializable.
 
+        Args:
+            request (django.http.HttpRequest):
+                The HTTP request from the client.
+
         Returns:
             dict:
             Model data to pass to the constructor of the JavaScript extension
diff --git a/djblets/extensions/templates/extensions/init_js_extensions.html b/djblets/extensions/templates/extensions/init_js_extensions.html
index 8889312d43cb00565cdf852eb7a9ba32270f0920..8fccf39557e6d728e17e83558e5b90df9e395756 100644
--- a/djblets/extensions/templates/extensions/init_js_extensions.html
+++ b/djblets/extensions/templates/extensions/init_js_extensions.html
@@ -1,16 +1,16 @@
 {% load djblets_js %}
 
-{% if js_extensions %}
+{% if js_extension_items %}
 <script>
-{%  for js_extension in js_extensions %}
-    new {{js_extension.model_class}}({
-{%   for key, value in js_extension.get_model_data.items %}
+{%  for item in js_extension_items %}
+    new {{item.js_extension.model_class}}({
+{%   for key, value in item.model_data.items %}
         {{key|json_dumps}}: {{value|json_dumps}},
 {%   endfor %}
-        id: '{{js_extension.extension.id}}',
-        name: '{{js_extension.extension.info.name|escapejs}}',
+        id: '{{item.js_extension.extension.id}}',
+        name: '{{item.js_extension.extension.info.name|escapejs}}',
         urlName: '{{url_name}}',
-        settings: {{js_extension.get_settings|json_dumps}}
+        settings: {{item.js_extension.get_settings|json_dumps}}
     });
 {%  endfor %}
 </script>
diff --git a/djblets/extensions/templatetags/djblets_extensions.py b/djblets/extensions/templatetags/djblets_extensions.py
index a31f939cc8ce5bef155d9f98e43e70e2c073b7fb..7db8e91baf463c36577a273cd27585060c1448de 100644
--- a/djblets/extensions/templatetags/djblets_extensions.py
+++ b/djblets/extensions/templatetags/djblets_extensions.py
@@ -1,6 +1,8 @@
 from __future__ import unicode_literals
 
+import inspect
 import logging
+import warnings
 
 from django import template
 from django.utils import six
@@ -328,7 +330,8 @@ def init_js_extensions(context, extension_manager_key):
     Each extension's required JavaScript files will be loaded in the page,
     and their JavaScript-side Extension subclasses will be instantiated.
     """
-    url_name = context['request'].resolver_match.url_name
+    request = context['request']
+    url_name = request.resolver_match.url_name
 
     for manager in get_extension_managers():
         if manager.key == extension_manager_key:
@@ -341,9 +344,29 @@ def init_js_extensions(context, extension_manager_key):
                     if js_extension.applies_to(url_name):
                         js_extensions.append(js_extension)
 
+            js_extension_items = []
+
+            for js_extension in js_extensions:
+                arg_spec = inspect.getargspec(js_extension.get_model_data)
+
+                if arg_spec.keywords is None:
+                    warnings.warn(
+                        '%s.get_model_data will need to take keyword '
+                        'arguments. The old function signature is deprecated.'
+                        % js_extension_cls.__name__)
+
+                    model_data = js_extension.get_model_data()
+                else:
+                    model_data = js_extension.get_model_data(request=request)
+
+                js_extension_items.append({
+                    'js_extension': js_extension,
+                    'model_data': model_data,
+                })
+
             return {
                 'url_name': url_name,
-                'js_extensions': js_extensions,
+                'js_extension_items': js_extension_items,
             }
 
     return {}
diff --git a/djblets/extensions/templatetags/tests.py b/djblets/extensions/templatetags/tests.py
index 7223350e2906d5f9dc7b9dd4f6e9a985aa6f4304..16f7d8b1c9f87ed1ab516401c39b1c3c97c28676 100644
--- a/djblets/extensions/templatetags/tests.py
+++ b/djblets/extensions/templatetags/tests.py
@@ -1,17 +1,33 @@
 from __future__ import unicode_literals
 
+import re
 import uuid
 
 from django.core.urlresolvers import ResolverMatch
 from django.http import HttpRequest
 from django.template import Context, Template
 
+from djblets.extensions.extension import JSExtension
 from djblets.extensions.hooks import TemplateHook
 from djblets.extensions.tests import (FakeEntryPoint, TestExtensionManager,
                                       TestExtensionWithRegistration)
 from djblets.testing.testcases import TestCase
 
 
+class TestJSExtension(JSExtension):
+    model_class = 'FooNew'
+
+    def get_model_data(self, request, **kwargs):
+        return {'test': 'new'}
+
+
+class TestJSExtensionDeprecated(JSExtension):
+    model_class = 'FooOld'
+
+    def get_model_data(self):
+        return {'test': 'old'}
+
+
 class TemplateTagTests(TestCase):
     """Tests for djblets.extensions.templatetags."""
 
@@ -30,6 +46,8 @@ class TemplateTagTests(TestCase):
             },
         }
 
+        js_extensions = [TestJSExtension, TestJSExtensionDeprecated]
+
     def setUp(self):
         self.key = uuid.uuid4()
 
@@ -148,3 +166,26 @@ class TemplateTagTests(TestCase):
             'default.min.js\n'
             '/ext/djblets.extensions.templatetags.tests.TestExtension/js/'
             'optional.min.js\n')
+
+    def test_init_js_extensions(self):
+        """Testing init_js_extensions template tag"""
+        t = Template('{% load djblets_extensions %}'
+                     '{% init_js_extensions manager_id %}')
+
+        self.manager.load()
+        self.manager.enable_extension(self.extension.id)
+        self.request.resolver_match = ResolverMatch(None, None, None, 'foo')
+
+        content = t.render(Context({
+            'ext': self.extension,
+            'manager_id': self.key,
+            'request': self.request,
+        }))
+
+        self.assertIsNotNone(re.search(
+            r'new FooNew\({\s+"test": "new",',
+            content))
+
+        self.assertIsNotNone(re.search(
+            r'new FooOld\({\s+"test": "old",',
+            content))
