diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7a306dd..a92aa17 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -8,9 +8,28 @@ on:
- '**'
jobs:
+ pre_commit:
+ name: Pre-commit
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.11
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install pre-commit
+
+ - name: Run pre-commit
+ run: pre-commit run --all-files --show-diff-on-failure
+
run_unittest_tests:
name: Unittest
runs-on: ${{ matrix.os }}
+ needs: pre_commit
strategy:
matrix:
os: [ubuntu-latest]
@@ -37,23 +56,23 @@ jobs:
tox-env: "django-50"
- python-version: "3.9"
tox-env: "django-50"
-
+
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
-
+
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install --only test
-
+
- name: Test with tox
run: poetry run tox -e py${{ matrix.python-version }}-${{ matrix.tox-env }}
-
+
- name: Report to codecov
if: success()
uses: codecov/codecov-action@v1
@@ -78,7 +97,7 @@ jobs:
uses: actions/setup-python@v2
with:
python-version: 3.11
-
+
- name: Install dependencies
run: |
python -m pip install --upgrade pip
diff --git a/README.rst b/README.rst
index 30fdf60..fe0c807 100644
--- a/README.rst
+++ b/README.rst
@@ -90,7 +90,7 @@ ACTIVE_LINK_STRICT Designates whether to perform a strict match or not. `Fals
For more usage examples, please check the full documentation at https://django-active-link.readthedocs.io.
-**IMPORTANT**: Django Active Link requires that the current request object is available in your template's context. This means you must be using a `RequestContext` when rendering your template, and `django.core.context_processors.request` must be in your `TEMPLATE_CONTEXT_PROCESSORS` setting. See https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext for more information.
+**IMPORTANT**: Django Active Link requires that the current request object is available in your template's context. This means you must be using a `RequestContext` when rendering your template, and `django.template.context_processors.request` must be in your `TEMPLATE_CONTEXT_PROCESSORS` setting. See https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext for more information.
TODO
----
diff --git a/active_link/templatetags/active_link_tags.py b/active_link/templatetags/active_link_tags.py
index ae306be..70a6a0b 100644
--- a/active_link/templatetags/active_link_tags.py
+++ b/active_link/templatetags/active_link_tags.py
@@ -1,12 +1,6 @@
-from django import VERSION as DJANGO_VERSION
from django import template
from django.conf import settings
-
-if DJANGO_VERSION[0] == 1 and DJANGO_VERSION[1] <= 9:
- from django.core.urlresolvers import NoReverseMatch, reverse
-else:
- from django.urls import reverse, NoReverseMatch
-
+from django.urls import NoReverseMatch, reverse
from django.utils.encoding import escape_uri_path
register = template.Library()
@@ -43,6 +37,7 @@ def active_link(
active = False
views = viewnames.split("||")
+
for viewname in views:
try:
path = reverse(viewname.strip(), args=args, kwargs=kwargs)
diff --git a/docs/installation.rst b/docs/installation.rst
index b3a8d4f..e5638b4 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -21,4 +21,31 @@ Add `active_link` to your `INSTALLED_APPS`:
...
)
+Make sure `django.template.context_processors.request` is added in your template context_processors:
+
+.. code-block:: python
+
+ TEMPLATES = [
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": (os.path.join(BASE_DIR, "templates"),),
+ "APP_DIRS": True,
+ "OPTIONS": {
+ "context_processors": [
+ # Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
+ # list if you haven't customized them:
+ "django.contrib.auth.context_processors.auth",
+ "django.template.context_processors.request",
+ "django.template.context_processors.debug",
+ "django.template.context_processors.i18n",
+ "django.template.context_processors.media",
+ "django.template.context_processors.static",
+ "django.template.context_processors.tz",
+ "django.contrib.messages.context_processors.messages",
+ ],
+ "debug": True,
+ },
+ },
+ ]
+
That's it. You can start using Django Active Link in your templates.
diff --git a/pyproject.toml b/pyproject.toml
index d558383..c1024fe 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -26,7 +26,7 @@ classifiers = [
]
packages = [
{ include = "active_link" },
-]
+]
[tool.poetry.dependencies]
python = "^3.8"
diff --git a/tests/settings.py b/tests/settings.py
index d9a8bb8..e0b7013 100644
--- a/tests/settings.py
+++ b/tests/settings.py
@@ -3,8 +3,6 @@
import os
-import django
-
BASE_DIR = os.path.dirname(__file__)
DEBUG = True
@@ -31,10 +29,7 @@
SITE_ID = 1
-if django.VERSION >= (1, 10):
- MIDDLEWARE = ()
-else:
- MIDDLEWARE_CLASSES = ()
+MIDDLEWARE_CLASSES = ()
TEMPLATES = [
{
@@ -46,6 +41,7 @@
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
# list if you haven't customized them:
"django.contrib.auth.context_processors.auth",
+ "django.template.context_processors.request",
"django.template.context_processors.debug",
"django.template.context_processors.i18n",
"django.template.context_processors.media",
diff --git a/tests/templates/detailed_action_kwargs.html b/tests/templates/detailed_action_kwargs.html
new file mode 100644
index 0000000..fdd27fd
--- /dev/null
+++ b/tests/templates/detailed_action_kwargs.html
@@ -0,0 +1,14 @@
+{% load active_link_tags %}
+
+
+
+
+
+ Simple test
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/templates/detailed_action_kwargs_multiple.html b/tests/templates/detailed_action_kwargs_multiple.html
new file mode 100644
index 0000000..e9bf271
--- /dev/null
+++ b/tests/templates/detailed_action_kwargs_multiple.html
@@ -0,0 +1,14 @@
+{% load active_link_tags %}
+
+
+
+
+
+ Simple test
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/templates/simple.html b/tests/templates/simple.html
new file mode 100644
index 0000000..749821c
--- /dev/null
+++ b/tests/templates/simple.html
@@ -0,0 +1,14 @@
+{% load active_link_tags %}
+
+
+
+
+
+ Simple test
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/templates/simple_custom_class.html b/tests/templates/simple_custom_class.html
new file mode 100644
index 0000000..b9b8684
--- /dev/null
+++ b/tests/templates/simple_custom_class.html
@@ -0,0 +1,14 @@
+{% load active_link_tags %}
+
+
+
+
+
+ Simple test
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/templates/simple_strict.html b/tests/templates/simple_strict.html
new file mode 100644
index 0000000..32291fb
--- /dev/null
+++ b/tests/templates/simple_strict.html
@@ -0,0 +1,14 @@
+{% load active_link_tags %}
+
+
+
+
+
+ Simple test
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/templates/simple_strict_no_match.html b/tests/templates/simple_strict_no_match.html
new file mode 100644
index 0000000..3b24d6f
--- /dev/null
+++ b/tests/templates/simple_strict_no_match.html
@@ -0,0 +1,14 @@
+{% load active_link_tags %}
+
+
+
+
+
+ Simple test
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/test_tags.py b/tests/test_tags.py
index fd3fb5b..28ce1c8 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -1,156 +1,57 @@
from django.template import Context, Template
-from django.test import TestCase, override_settings
-from django.test.client import RequestFactory
+from django.test import Client, TestCase, override_settings
+from django.urls import reverse
class TestActiveLink(TestCase):
def setUp(self):
- self.client = RequestFactory()
+ self.client = Client()
+
+ def reverse_helper(self, reverse_url_string, kwargs=None):
+ if kwargs:
+ reverse_url = reverse(reverse_url_string, kwargs=kwargs)
+ else:
+ reverse_url = reverse(reverse_url_string)
+ response = self.client.get(reverse_url)
+ content = response.content.decode()
+ return content
def test_no_request(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple' %}
- """
- )
+ template = Template("simple.html")
context = Context({"request": None})
html = template.render(context)
- assert "active" not in html
+ self.assertNotIn("active", html)
def test_match_defaults(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple' %}
- """
- )
- context = Context({"request": self.client.get("/simple/")})
- html = template.render(context)
- assert "active" in html
-
- def test_match_defaults_with_multiple_view_name(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple || multiple' %}
- """
- )
- context0 = Context({"request": self.client.get("/simple/")})
- context1 = Context({"request": self.client.get("/multiple/")})
- html0 = template.render(context0)
- html1 = template.render(context1)
- assert "active" in html0
- assert "active" in html1
-
- def test_match_not_strict(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple' %}
- """
- )
- context = Context({"request": self.client.get("/simple/action/")})
- html = template.render(context)
- assert "active" in html
-
- def test_no_match_not_strict(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple-action' %}
- """
- )
- context = Context({"request": self.client.get("/other/action/")})
- html = template.render(context)
- assert "active" not in html
-
- def test_no_match_not_strict_with_multiple_view_name(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple-action || multiple-action' %}
- """
- )
- context = Context({"request": self.client.get("/other/action/")})
- html = template.render(context)
- assert "active" not in html
+ content = self.reverse_helper("simple")
+ self.assertInHTML('', content)
def test_match_strict(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple-action' strict=True %}
- """
- )
- context = Context({"request": self.client.get("/simple/action/")})
- html = template.render(context)
- assert "active" in html
+ content = self.reverse_helper("simple-action")
+ self.assertInHTML('
', content)
def test_no_match_strict(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple-action' strict=True %}
- """
- )
- context = Context({"request": self.client.get("/simple/")})
- html = template.render(context)
- assert "active" not in html
+ content = self.reverse_helper("simple-strict-no-match")
+ self.assertNotIn('
', content)
def test_custom_class(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple' 'my-active-class' %}
- """
- )
- context = Context({"request": self.client.get("/simple/")})
- html = template.render(context)
- assert "my-active-class" in html
+ content = self.reverse_helper("simple-custom-class")
+ self.assertInHTML('
', content)
@override_settings(ACTIVE_LINK_CSS_CLASS="my-active-class")
def test_settings_css_class(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple' %}
- """
- )
- context = Context({"request": self.client.get("/simple/")})
- html = template.render(context)
- assert "my-active-class" in html
+ content = self.reverse_helper("simple")
+ self.assertInHTML('
', content)
@override_settings(ACTIVE_LINK_STRICT=True)
def test_settings_strict(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple-action' %}
- """
- )
- context = Context({"request": self.client.get("/simple/")})
- html = template.render(context)
- assert "active" not in html
+ content = self.reverse_helper("simple-settings-strict")
+ self.assertNotIn('
', content)
def test_match_url_with_kwargs(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'detailed-action' pk=12 %}
- """
- )
- context = Context({"request": self.client.get("/detailed/action/12/")})
- html = template.render(context)
- assert "active" in html
+ content = self.reverse_helper("detailed-action", {"pk": 12})
+ self.assertInHTML('
', content)
def test_match_url_with_kwargs_with_multiple(self):
- template = Template(
- """
- {% load active_link_tags %}
- {% active_link 'simple || detailed-action' pk=12 %}
- """
- )
- context = Context({"request": self.client.get("/detailed/action/12/")})
- html = template.render(context)
- assert "active" in html
+ content = self.reverse_helper("detailed-action-multiple", {"pk": 12})
+ self.assertInHTML('
', content)
diff --git a/tests/urls.py b/tests/urls.py
index f9f0512..576ba6c 100644
--- a/tests/urls.py
+++ b/tests/urls.py
@@ -2,13 +2,38 @@
from __future__ import absolute_import, unicode_literals
from django.urls import path
-from django.views.generic import View
+from django.views.generic import TemplateView
urlpatterns = [
- path(r"simple/", View.as_view(), name="simple"),
- path(r"multiple/", View.as_view(), name="multiple"),
- path(r"simple/action/", View.as_view(), name="simple-action"),
- path(r"multiple/action/", View.as_view(), name="multiple-action"),
- path(r"other/action/", View.as_view(), name="other-action"),
- path(r"detailed/action//", View.as_view(), name="detailed-action"),
+ path(r"simple/", TemplateView.as_view(template_name="simple.html"), name="simple"),
+ path(
+ r"simple/strict_no_match/",
+ TemplateView.as_view(template_name="simple_strict_no_match.html"),
+ name="simple-strict-no-match",
+ ),
+ path(
+ r"simple/custom-class/",
+ TemplateView.as_view(template_name="simple_custom_class.html"),
+ name="simple-custom-class",
+ ),
+ path(
+ r"simple/settings-strict/",
+ TemplateView.as_view(template_name="simple.html"),
+ name="simple-settings-strict",
+ ),
+ path(
+ r"simple/action/",
+ TemplateView.as_view(template_name="simple_strict.html"),
+ name="simple-action",
+ ),
+ path(
+ r"detailed/action//",
+ TemplateView.as_view(template_name="detailed_action_kwargs.html"),
+ name="detailed-action",
+ ),
+ path(
+ r"detailed/action/multiple//",
+ TemplateView.as_view(template_name="detailed_action_kwargs_multiple.html"),
+ name="detailed-action-multiple",
+ ),
]