Skip to content

Commit f3bccff

Browse files
committed
Refactor as_css_class to 'to_kebabcase'.
We're making a few changes here - Changing the name to 'to_kebabcase' - Covering all edge cases - Adding a unit test for this utility
1 parent 6ca6000 commit f3bccff

File tree

9 files changed

+80
-53
lines changed

9 files changed

+80
-53
lines changed

pydis_site/apps/resources/templatetags/as_css_class.py

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import re
2+
3+
from django import template
4+
5+
REGEX_CONSECUTIVE_NON_LETTERS = r"[^A-Za-z0-9]+"
6+
register = template.Library()
7+
8+
9+
def _to_kebabcase(class_name: str) -> str:
10+
"""
11+
Convert any string to kebab-case.
12+
13+
For example, convert
14+
"__Favorite FROOT¤#/$?is----LeMON???" to
15+
"favorite-froot-is-lemon"
16+
"""
17+
# First, make it lowercase, and just remove any apostrophes.
18+
# We remove the apostrophes because "wasnt" is better than "wasn-t"
19+
class_name = class_name.casefold()
20+
class_name = class_name.replace("'", '')
21+
22+
# Now, replace any non-letter that remains with a dash.
23+
# If there are multiple consecutive non-letters, just replace them with a single dash.
24+
# my-favorite-class is better than my-favorite------class
25+
class_name = re.sub(
26+
REGEX_CONSECUTIVE_NON_LETTERS,
27+
"-",
28+
class_name,
29+
)
30+
31+
# Now we use strip to get rid of any leading or trailing dashes.
32+
class_name = class_name.strip("-")
33+
return class_name
34+
35+
36+
@register.filter
37+
def to_kebabcase(class_name: str) -> str:
38+
"""Convert a string to kebab-case."""
39+
return _to_kebabcase(class_name)

pydis_site/apps/resources/tests/test_resources.py

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from django.test import TestCase
2+
3+
from pydis_site.apps.resources.templatetags.to_kebabcase import _to_kebabcase
4+
5+
6+
class TestToKebabcase(TestCase):
7+
"""Tests for the `as_css_class` template tag."""
8+
9+
def test_to_kebabcase(self):
10+
"""Test the to_kebabcase utility and template tag."""
11+
weird_input = (
12+
"_-_--_A_LEm0n?in&¤'the##trEE£$@€@€@@£is-NOT----QUITE//"
13+
"as#good! as one __IN-YOUR|||HaND"
14+
)
15+
16+
self.assertEqual(
17+
_to_kebabcase(weird_input),
18+
"a-lem0n-in-the-tree-is-not-quite-as-good-as-one-in-your-hand",
19+
)

pydis_site/apps/resources/tests/testing_resources/testing/foobar/resource_test.yaml

Lines changed: 0 additions & 1 deletion
This file was deleted.

pydis_site/apps/resources/tests/testing_resources/testing/my_resource.yaml

Lines changed: 0 additions & 1 deletion
This file was deleted.

pydis_site/apps/resources/views/resources.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from django.views import View
1010

1111
from pydis_site import settings
12-
from pydis_site.apps.resources.templatetags.as_css_class import as_css_class
12+
from pydis_site.apps.resources.templatetags.to_kebabcase import to_kebabcase
1313

1414
RESOURCES_PATH = Path(settings.BASE_DIR, "pydis_site", "apps", "resources", "resources")
1515

@@ -58,9 +58,7 @@ def __init__(self, *args, **kwargs):
5858

5959
# Make a CSS class friendly representation too, while we're already iterating.
6060
for tag in tags:
61-
css_tag = f"{tag_type}-{tag}"
62-
css_tag = css_tag.replace("_", "-")
63-
css_tag = css_tag.replace(" ", "-")
61+
css_tag = to_kebabcase(f"{tag_type}-{tag}")
6462
css_classes.append(css_tag)
6563

6664
# Now add the css classes back to the resource, so we can use them in the template.
@@ -96,12 +94,12 @@ def __init__(self, *args, **kwargs):
9694

9795
# A complete list of valid filter names
9896
self.valid_filters = {
99-
"topics": [as_css_class(topic) for topic in self.filters["Topics"]["filters"]],
97+
"topics": [to_kebabcase(topic) for topic in self.filters["Topics"]["filters"]],
10098
"payment_tiers": [
101-
as_css_class(tier) for tier in self.filters["Payment tiers"]["filters"]
99+
to_kebabcase(tier) for tier in self.filters["Payment tiers"]["filters"]
102100
],
103-
"type": [as_css_class(type_) for type_ in self.filters["Type"]["filters"]],
104-
"difficulty": [as_css_class(tier) for tier in self.filters["Difficulty"]["filters"]],
101+
"type": [to_kebabcase(type_) for type_ in self.filters["Type"]["filters"]],
102+
"difficulty": [to_kebabcase(tier) for tier in self.filters["Difficulty"]["filters"]],
105103
}
106104

107105
def get(self, request: WSGIRequest, resource_type: t.Optional[str] = None) -> HttpResponse:

pydis_site/templates/resources/resource_box.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{% load as_icon %}
2-
{% load as_css_class %}
2+
{% load to_kebabcase %}
33
{% load get_category_icon %}
44

55
<div class="box resource-box {{ resource.css_classes }}">
@@ -38,7 +38,7 @@
3838
<span
3939
class="tag resource-tag is-primary is-light ml-2 mt-2"
4040
data-filter-name="topics"
41-
data-filter-item="{{ tag|as_css_class }}"
41+
data-filter-item="{{ tag|to_kebabcase }}"
4242
>
4343
<i class="{{ tag|title|get_category_icon }} mr-1"></i>
4444
{{ tag|title }}
@@ -48,7 +48,7 @@
4848
<span
4949
class="tag resource-tag has-background-success-light has-text-success-dark ml-2 mt-2"
5050
data-filter-name="type"
51-
data-filter-item="{{ tag|as_css_class }}"
51+
data-filter-item="{{ tag|to_kebabcase }}"
5252
>
5353
<i class="{{ tag|title|get_category_icon }} mr-1"></i>
5454
{{ tag|title }}
@@ -58,7 +58,7 @@
5858
<span
5959
class="tag resource-tag has-background-danger-light has-text-danger-dark ml-2 mt-2"
6060
data-filter-name="payment-tiers"
61-
data-filter-item="{{ tag|as_css_class }}"
61+
data-filter-item="{{ tag|to_kebabcase }}"
6262
>
6363
<i class="{{ tag|title|get_category_icon }} mr-1"></i>
6464
{{ tag|title }}
@@ -68,7 +68,7 @@
6868
<span
6969
class="tag resource-tag has-background-info-light has-text-info-dark ml-2 mt-2"
7070
data-filter-name="difficulty"
71-
data-filter-item="{{ tag|as_css_class }}"
71+
data-filter-item="{{ tag|to_kebabcase }}"
7272
>
7373
<i class="{{ tag|title|get_category_icon }} mr-1"></i>
7474
{{ tag|title }}

pydis_site/templates/resources/resources.html

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{% extends 'base/base.html' %}
22
{% load as_icon %}
3-
{% load as_css_class %}
3+
{% load to_kebabcase %}
44
{% load get_category_icon %}
55
{% load static %}
66

@@ -44,8 +44,8 @@
4444
{% if filter_name == "Difficulty" %}
4545
<span
4646
class="filter-box-tag tag has-background-info-light has-text-info-dark ml-2 mt-2"
47-
data-filter-name="{{ filter_name|as_css_class }}"
48-
data-filter-item="{{ filter_item|as_css_class }}"
47+
data-filter-name="{{ filter_name|to_kebabcase }}"
48+
data-filter-item="{{ filter_item|to_kebabcase }}"
4949
>
5050
<i class="{{ filter_item|title|get_category_icon }} mr-1"></i>
5151
{{ filter_item|title }}
@@ -55,8 +55,8 @@
5555
{% if filter_name == "Type" %}
5656
<span
5757
class="filter-box-tag tag has-background-success-light has-text-success-dark ml-2 mt-2"
58-
data-filter-name="{{ filter_name|as_css_class }}"
59-
data-filter-item="{{ filter_item|as_css_class }}"
58+
data-filter-name="{{ filter_name|to_kebabcase }}"
59+
data-filter-item="{{ filter_item|to_kebabcase }}"
6060
>
6161
<i class="{{ filter_item|title|get_category_icon }} mr-1"></i>
6262
{{ filter_item|title }}
@@ -66,8 +66,8 @@
6666
{% if filter_name == "Payment tiers" %}
6767
<span
6868
class="filter-box-tag tag has-background-danger-light has-text-danger-dark ml-2 mt-2"
69-
data-filter-name="{{ filter_name|as_css_class }}"
70-
data-filter-item="{{ filter_item|as_css_class }}"
69+
data-filter-name="{{ filter_name|to_kebabcase }}"
70+
data-filter-item="{{ filter_item|to_kebabcase }}"
7171
>
7272
<i class="{{ filter_item|title|get_category_icon }} mr-1"></i>
7373
{{ filter_item|title }}
@@ -77,8 +77,8 @@
7777
{% if filter_name == "Topics" %}
7878
<span
7979
class="filter-box-tag tag is-primary is-light ml-2 mt-2"
80-
data-filter-name="{{ filter_name|as_css_class }}"
81-
data-filter-item="{{ filter_item|as_css_class }}"
80+
data-filter-name="{{ filter_name|to_kebabcase }}"
81+
data-filter-item="{{ filter_item|to_kebabcase }}"
8282
>
8383
<i class="{{ filter_item|title|get_category_icon }} mr-1"></i>
8484
{{ filter_item|title }}
@@ -127,8 +127,8 @@
127127
<input
128128
class="filter-checkbox"
129129
type="checkbox"
130-
data-filter-name="{{ filter_name|as_css_class }}"
131-
data-filter-item="{{ filter_item|as_css_class }}"
130+
data-filter-name="{{ filter_name|to_kebabcase }}"
131+
data-filter-item="{{ filter_item|to_kebabcase }}"
132132
>
133133
{{ filter_item }}
134134
</label>

0 commit comments

Comments
 (0)