Skip to content

Commit 83f3eec

Browse files
authored
feat: enable editing of media slug, show categories on manage media
1 parent a5acce4 commit 83f3eec

File tree

14 files changed

+85
-9
lines changed

14 files changed

+85
-9
lines changed

cms/settings.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,8 @@
503503
USE_ROUNDED_CORNERS = True
504504

505505
ALLOW_VIDEO_TRIMMER = True
506+
507+
ALLOW_CUSTOM_MEDIA_URLS = False
506508
try:
507509
# keep a local_settings.py file for local overrides
508510
from .local_settings import * # noqa

cms/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = "6.0.1"
1+
VERSION = "6.1.0"

docs/admins_docs.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
- [22. Role-Based Access Control](#22-role-based-access-control)
2626
- [23. SAML setup](#23-saml-setup)
2727
- [24. Identity Providers setup](#24-identity-providers-setup)
28-
28+
- [25. Custom urls](#25-custom-urls)
2929

3030

3131
## 1. Welcome
@@ -965,3 +965,6 @@ USE_IDENTITY_PROVIDERS = True
965965

966966
Visiting the admin, you will see the Identity Providers tab and you can add one.
967967

968+
## 25. Custom urls
969+
To enable custom urls, set `ALLOW_CUSTOM_MEDIA_URLS = True` on settings.py or local_settings.py
970+
This will enable editing the URL of the media, while editing a media. If the URL is already taken you get a message you cannot update this.

files/forms.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class MediaMetadataForm(forms.ModelForm):
2222
class Meta:
2323
model = Media
2424
fields = (
25+
"friendly_token",
2526
"title",
2627
"new_tags",
2728
"add_date",
@@ -38,18 +39,22 @@ class Meta:
3839
"thumbnail_time": forms.NumberInput(attrs={'min': 0, 'step': 0.1}),
3940
}
4041
labels = {
42+
"friendly_token": "Slug",
4143
"uploaded_poster": "Poster Image",
4244
"thumbnail_time": "Thumbnail Time (seconds)",
4345
}
4446
help_texts = {
4547
"title": "",
48+
"friendly_token": "Media URL slug",
4649
"thumbnail_time": "Select the time in seconds for the video thumbnail",
4750
"uploaded_poster": "Maximum file size: 5MB",
4851
}
4952

5053
def __init__(self, user, *args, **kwargs):
5154
self.user = user
5255
super(MediaMetadataForm, self).__init__(*args, **kwargs)
56+
if not getattr(settings, 'ALLOW_CUSTOM_MEDIA_URLS', False):
57+
self.fields.pop("friendly_token")
5358
if self.instance.media_type != "video":
5459
self.fields.pop("thumbnail_time")
5560
if self.instance.media_type == "image":
@@ -74,9 +79,22 @@ def __init__(self, user, *args, **kwargs):
7479

7580
if self.instance.media_type == "video":
7681
self.helper.layout.append(CustomField('thumbnail_time'))
82+
if getattr(settings, 'ALLOW_CUSTOM_MEDIA_URLS', False):
83+
self.helper.layout.insert(0, CustomField('friendly_token'))
7784

7885
self.helper.layout.append(FormActions(Submit('submit', 'Update Media', css_class='primaryAction')))
7986

87+
def clean_friendly_token(self):
88+
token = self.cleaned_data.get("friendly_token", "").strip()
89+
90+
if token:
91+
if not all(c.isalnum() or c in "-_" for c in token):
92+
raise forms.ValidationError("Slug can only contain alphanumeric characters, underscores, or hyphens.")
93+
94+
if Media.objects.filter(friendly_token=token).exclude(pk=self.instance.pk).exists():
95+
raise forms.ValidationError("This slug is already in use. Please choose a different one.")
96+
return token
97+
8098
def clean_uploaded_poster(self):
8199
image = self.cleaned_data.get("uploaded_poster", False)
82100
if image:

files/management_views.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def get(self, request, format=None):
4646

4747
featured = params.get("featured", "").strip()
4848
is_reviewed = params.get("is_reviewed", "").strip()
49+
category = params.get("category", "").strip()
4950

5051
sort_by_options = [
5152
"title",
@@ -98,6 +99,9 @@ def get(self, request, format=None):
9899
if is_reviewed != "all":
99100
qs = qs.filter(is_reviewed=is_reviewed)
100101

102+
if category:
103+
qs = qs.filter(category__title__contains=category)
104+
101105
media = qs.order_by(f"{ordering}{sort_by}")
102106

103107
paginator = pagination_class()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Django 5.1.6 on 2025-06-20 08:13
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
('files', '0008_alter_media_state_videotrimrequest'),
9+
]
10+
11+
operations = [
12+
migrations.AlterField(
13+
model_name='media',
14+
name='friendly_token',
15+
field=models.CharField(blank=True, db_index=True, help_text='Identifier for the Media', max_length=150, unique=True),
16+
),
17+
]

files/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class Media(models.Model):
155155
help_text="Whether media is globally featured by a MediaCMS editor",
156156
)
157157

158-
friendly_token = models.CharField(blank=True, max_length=12, db_index=True, help_text="Identifier for the Media")
158+
friendly_token = models.CharField(blank=True, max_length=150, db_index=True, unique=True, help_text="Identifier for the Media")
159159

160160
hls_file = models.CharField(max_length=1000, blank=True, help_text="Path to HLS file for videos")
161161

files/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
re_path(r"^api/v1/media$", views.MediaList.as_view()),
5252
re_path(r"^api/v1/media/$", views.MediaList.as_view()),
5353
re_path(
54-
r"^api/v1/media/(?P<friendly_token>[\w]*)$",
54+
r"^api/v1/media/(?P<friendly_token>[\w\-_]*)$",
5555
views.MediaDetail.as_view(),
5656
name="api_get_media",
5757
),

files/views.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,21 +506,29 @@ def liked_media(request):
506506
def manage_users(request):
507507
"""List users management view"""
508508

509+
if not is_mediacms_editor(request.user):
510+
return HttpResponseRedirect("/")
511+
509512
context = {}
510513
return render(request, "cms/manage_users.html", context)
511514

512515

513516
@login_required
514517
def manage_media(request):
515518
"""List media management view"""
519+
if not is_mediacms_editor(request.user):
520+
return HttpResponseRedirect("/")
516521

517-
context = {}
522+
categories = Category.objects.all().order_by('title').values_list('title', flat=True)
523+
context = {'categories': list(categories)}
518524
return render(request, "cms/manage_media.html", context)
519525

520526

521527
@login_required
522528
def manage_comments(request):
523529
"""List comments management view"""
530+
if not is_mediacms_editor(request.user):
531+
return HttpResponseRedirect("/")
524532

525533
context = {}
526534
return render(request, "cms/manage_comments.html", context)

frontend/src/static/js/components/management-table/ManageItemList-filters.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
}
6767

6868
@media (min-width: 1024px) {
69-
width: 20%;
69+
width: 10%;
7070

7171
&:nth-child(3n + 1),
7272
&:nth-child(3n + 2),

0 commit comments

Comments
 (0)