Skip to content

Commit

Permalink
Fix Unicode chars handling in urls (nephila#654)
Browse files Browse the repository at this point in the history
* Fix Unicode chars in urls
Handle unicode chars in reverse of Post and Category models, using Django path() method instead of url()

Closes nephila#653

Co-authored-by: Benjamin PIERRE <[email protected]>
  • Loading branch information
pierreben and Benjamin PIERRE authored Dec 4, 2020
1 parent 83e76f1 commit a2a62c6
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 15 deletions.
1 change: 1 addition & 0 deletions changes/653.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Handle unicode chars in reverse of Post and Category models, using Django path() method instead of url()
4 changes: 2 additions & 2 deletions djangocms_blog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,9 @@ def get_absolute_url(self, lang=None):
kwargs["month"] = "%02d" % current_date.month
if "<int:day>" in urlconf:
kwargs["day"] = "%02d" % current_date.day
if "<slug:slug>" in urlconf:
if "<str:slug>" in urlconf or "<slug:slug>" in urlconf:
kwargs["slug"] = self.safe_translation_getter("slug", language_code=lang, any_language=True) # NOQA
if "<slug:category>" in urlconf:
if "<slug:category>" in urlconf or "<str:category>" in urlconf:
kwargs["category"] = category.safe_translation_getter(
"slug", language_code=lang, any_language=True
) # NOQA
Expand Down
9 changes: 5 additions & 4 deletions djangocms_blog/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@
"""

PERMALINKS_URLS = { # noqa
PERMALINK_TYPE_FULL_DATE: "<int:year>/<int:month>/<int:day>/<slug:slug>/",
PERMALINK_TYPE_SHORT_DATE: "<int:year>/<int:month>/<slug:slug>/",
PERMALINK_TYPE_CATEGORY: "<slug:category>/<slug:slug>/",
PERMALINK_TYPE_SLUG: "<slug:slug>/",
PERMALINK_TYPE_FULL_DATE: "<int:year>/<int:month>/<int:day>/<str:slug>/",
PERMALINK_TYPE_SHORT_DATE: "<int:year>/<int:month>/<str:slug>/",
PERMALINK_TYPE_CATEGORY: "<str:category>/<str:slug>/",
PERMALINK_TYPE_SLUG: "<str:slug>/",
}

"""
.. _PERMALINKS_URLS:
Expand Down
2 changes: 1 addition & 1 deletion djangocms_blog/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_urls():
path("<int:year>/", PostArchiveView.as_view(), name="posts-archive"),
path("<int:year>/<int:month>/", PostArchiveView.as_view(), name="posts-archive"),
path("author/<str:username>/", AuthorEntriesView.as_view(), name="posts-author"),
path("category/<slug:category>/", CategoryEntriesView.as_view(), name="posts-category"),
path("category/<str:category>/", CategoryEntriesView.as_view(), name="posts-category"),
path("tag/<slug:tag>/", TaggedListView.as_view(), name="posts-tagged"),
path("tag/<slug:tag>/feed/", TagFeed(), name="posts-tagged-feed"),
] + detail_urls
6 changes: 3 additions & 3 deletions docs/features/home.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ To avoid this add the following settings to you project:
('category', _('Category')),
)
BLOG_PERMALINK_URLS = {
"full_date": "<int:year>/<int:month>/<int:day>/<slug:slug>/",
"short_date: "<int:year>/<int:month>/<slug:slug>/",
"category": "<slug:category>/<slug:slug>/",
"full_date": "<int:year>/<int:month>/<int:day>/<str:slug>/",
"short_date: "<int:year>/<int:month>/<str:slug>/",
"category": "<str:category>/<str:slug>/",
}
Notice that the last permalink type is no longer present.
Expand Down
8 changes: 4 additions & 4 deletions docs/features/permalinks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ like the following in the project settings:
.. code-block:: python
BLOG_PERMALINK_URLS = {
"full_date": "<int:year>/<int:month>/<int:day>/<slug:slug>/",
"short_date: "<int:year>/<int:month>/<slug:slug>/",
"category": "<slug:category>/<slug:slug>/",
"slug": "<slug:slug>/",
"full_date": "<int:year>/<int:month>/<int:day>/<str:slug>/",
"short_date: "<int:year>/<int:month>/<str:slug>/",
"category": "<str:category>/<str:slug>/",
"slug": "<str:slug>/",
}
And change ``post/`` with the desired prefix.
Expand Down
38 changes: 38 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from django.urls import reverse
from django.utils.encoding import force_str
from django.utils.html import strip_tags
from django.utils.http import urlquote
from django.utils.timezone import now
from django.utils.translation import get_language, override
from filer.models import ThumbnailOption
Expand Down Expand Up @@ -853,6 +854,10 @@ def test_slug(self):
post = Post.objects.language("en").create(title="I am a title")
self.assertEqual(post.slug, "i-am-a-title")

# Test unicode chars in slugs
post = Post.objects.language("fr").create(title="Accentué")
self.assertEqual(post.slug, "accentué")

def test_model_attributes(self):
self.get_pages()

Expand Down Expand Up @@ -1032,6 +1037,39 @@ def test_urls(self):
post.app_config = self.app_config_1
self.assertTrue(re.match(r".*/%s/$" % post.slug, post.get_absolute_url()))

# Unicode chars in slugs
post = Post.objects.language("fr").create(title="Accentué")
category = BlogCategory.objects.create(name="Catégorie 2", app_config=self.app_config_1)
category.set_current_language("fr", initialize=True)
post.categories.add(category)

# full date
self.app_config_1.app_data.config.url_patterns = "full_date"
self.app_config_1.save()
post.app_config = self.app_config_1
self.assertTrue(re.match(r".*\d{4}/\d{2}/\d{2}/%s/$" % urlquote(post.slug), post.get_absolute_url()))

# short date
self.app_config_1.app_data.config.url_patterns = "short_date"
self.app_config_1.save()
post.app_config = self.app_config_1
self.assertTrue(re.match(r".*\d{4}/\d{2}/%s/$" % urlquote(post.slug), post.get_absolute_url()))

# category
self.app_config_1.app_data.config.url_patterns = "category"
self.app_config_1.save()
post.app_config = self.app_config_1

self.assertTrue(
re.match(r".*{}/{}/$".format(urlquote(post.categories.first().slug), urlquote(post.slug)), post.get_absolute_url())
)

# slug only
self.app_config_1.app_data.config.url_patterns = "category"
self.app_config_1.save()
post.app_config = self.app_config_1
self.assertTrue(re.match(r".*/%s/$" % urlquote(post.slug), post.get_absolute_url()))

def test_url_language(self):
self.get_pages()
post = self._get_post(self._post_data[0]["en"])
Expand Down
2 changes: 1 addition & 1 deletion tests/test_utils/blog_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def get_urls():
path("<int:year>/", PostArchiveView.as_view(), name="posts-archive"),
path("<int:year>/<int:month>/", PostArchiveView.as_view(), name="posts-archive"),
path("author/<str:username>/", AuthorEntriesView.as_view(), name="posts-author"),
path("category/<slug:category>/", CategoryEntriesView.as_view(), name="posts-category"),
path("category/<str:category>/", CategoryEntriesView.as_view(), name="posts-category"),
path("tag/<slug:tag>/", TaggedListView.as_view(), name="posts-tagged"),
path("tag/<slug:tag>/feed/", TagFeed(), name="posts-tagged-feed"),
] + detail_urls

0 comments on commit a2a62c6

Please sign in to comment.