Add `frontend_url` field to wagtail pages

This commit is contained in:
Daniel Egger 2022-10-03 17:40:35 +02:00
parent 5b3a751704
commit cbdbdba6b8
19 changed files with 449 additions and 118 deletions

View File

@ -170,7 +170,7 @@ const profileDropdownData = [
Shop
</router-link>
<router-link
to="/media/versicherungsvermittlerin-media/overview"
to="/media/versicherungsvermittlerin-media"
class="nav-item"
:class="{ 'nav-item--active': isInRoutePath(['/media']) }"
>

View File

@ -67,10 +67,7 @@ export default {
const newCircle = {};
newCircle.pieData = pieData.reverse();
newCircle.title = circle.title;
newCircle.slug = circle.slug.replace(
`${circle.parentLearningPath.slug}-circle-`,
""
);
newCircle.frontend_url = circle.frontend_url;
newCircle.id = circle.id;
internalCircles.push(newCircle);
});
@ -155,7 +152,7 @@ export default {
});
})
.on("click", (d, i) => {
vueRouter.push(`/learn/${this.learningPathStore.learningPath.slug}/${i.slug}`);
vueRouter.push(i.frontend_url);
})
.attr("role", "button");

View File

@ -40,7 +40,8 @@ const router = createRouter({
},
{
path: "handlungsfelder",
component: () => import("@/views/media_library/MediaLibraryCategoryOverview.vue"),
component: () =>
import("@/views/media_library/MediaLibraryCategoryOverview.vue"),
},
{
path: "handlungsfeldlist",

View File

@ -21,6 +21,7 @@ function _createEmptyLearningUnit(
slug: "",
translation_key: "",
type: "learnpath.LearningUnit",
frontend_url: "",
learningContents: [],
minutes: 0,
parentLearningSequence: parentLearningSequence,
@ -131,7 +132,8 @@ export class Circle implements CourseWagtailPage {
public readonly slug: string,
public readonly title: string,
public readonly translation_key: string,
public description: string,
public readonly frontend_url: string,
public readonly description: string,
public children: CircleChild[],
public goals: CircleGoal[],
public job_situations: CircleJobSituation[],
@ -147,6 +149,7 @@ export class Circle implements CourseWagtailPage {
json.slug,
json.title,
json.translation_key,
json.frontend_url,
json.description,
json.children,
json.goals,
@ -241,9 +244,4 @@ export class Circle implements CourseWagtailPage {
this.parentLearningPath.calcNextLearningContent(completionData);
}
}
public getUrl(): string {
const shortSlug = this.slug.replace(`${this.parentLearningPath?.slug}-circle-`, "");
return `/learn/${this.parentLearningPath?.slug}/${shortSlug}`;
}
}

View File

@ -35,6 +35,7 @@ export class LearningPath implements CourseWagtailPage {
json.slug,
json.title,
json.translation_key,
json.frontend_url,
json.course.id,
json.children,
completionData
@ -46,6 +47,7 @@ export class LearningPath implements CourseWagtailPage {
public readonly slug: string,
public readonly title: string,
public readonly translation_key: string,
public readonly frontend_url: string,
public readonly courseId: number,
public children: LearningPathChild[],
completionData?: CourseCompletion[]

View File

@ -94,25 +94,23 @@ export const useCircleStore = defineStore({
}
},
openLearningContent(learningContent: LearningContent) {
const shortSlug = learningContent.slug.replace(`${this.circle?.slug}-lc-`, "");
this.router.push({
path: `${this.circle?.getUrl()}/${shortSlug}`,
path: learningContent.frontend_url,
});
},
closeLearningContent() {
this.router.push({
path: `${this.circle?.getUrl()}`,
path: `${this.circle?.frontend_url}`,
});
},
openSelfEvaluation(learningUnit: LearningUnit) {
const shortSlug = learningUnit.slug.replace(`${this.circle?.slug}-lu-`, "");
this.router.push({
path: `${this.circle?.getUrl()}/evaluate/${shortSlug}`,
path: learningUnit.frontend_url,
});
},
closeSelfEvaluation() {
this.router.push({
path: `${this.circle?.getUrl()}`,
path: `${this.circle?.frontend_url}`,
});
},
calcSelfEvaluationStatus(learningUnit: LearningUnit) {

View File

@ -119,6 +119,7 @@ export interface CourseWagtailPage {
readonly title: string;
readonly slug: string;
readonly translation_key: string;
readonly frontend_url: string;
completion_status: CourseCompletionStatus;
}

View File

@ -31,12 +31,9 @@ onMounted(async () => {
const createContinueUrl = (learningPath: LearningPath): [string, boolean] => {
if (learningPath.nextLearningContent) {
const circle = learningPath.nextLearningContent.parentCircle;
const lsShortSlug =
learningPath.nextLearningContent.parentLearningSequence?.slug.replace(
`${circle.slug}-`,
""
);
const url = `/learn/${learningPath.slug}/${learningPath.nextLearningContent.parentCircle.slug}#${lsShortSlug}`;
const url =
learningPath.nextLearningContent.parentLearningSequence?.frontend_url ||
circle.frontend_url;
const isFirst =
learningPath.nextLearningContent.translation_key ===
learningPath.circles[0].flatLearningContents[0].translation_key;

View File

@ -166,8 +166,8 @@ log.debug("MediaCategoryDetailView created", props.mediaCategorySlug);
const mediaStore = useMediaLibraryStore();
const mediaCategory = computed(() => {
return mediaStore.mediaLibraryPage?.children.find(
(category) => category.slug === props.mediaCategorySlug
return mediaStore.mediaLibraryPage?.children.find((category) =>
category.slug.endsWith(props.mediaCategorySlug)
);
});

View File

@ -28,9 +28,7 @@ watch(dropdownSelected, (newValue) =>
:key="cat.id"
class="bg-white p-4"
>
<router-link
:to="`/media/${mediaStore.mediaLibraryPage.slug}/handlungsfelder/${cat.slug}`"
>
<router-link :to="cat.frontend_url">
<img class="m-auto" :src="`/static/icons/demo/${cat.overview_icon}.svg`" />
<h3 class="text-base text-center">{{ cat.title }}</h3>
</router-link>

View File

@ -28,11 +28,6 @@ class CompetenceProfilePage(Page):
return get_it_serializer_class(
cls,
[
"id",
"title",
"slug",
"type",
"translation_key",
"course",
"children",
],
@ -69,11 +64,6 @@ class CompetencePage(Page):
return get_it_serializer_class(
cls,
[
"id",
"title",
"slug",
"type",
"translation_key",
"children",
],
)

View File

@ -1,4 +1,5 @@
import structlog
from django.views.decorators.cache import cache_page
from rest_framework.decorators import api_view
from rest_framework.response import Response
from wagtail.models import Page
@ -11,7 +12,7 @@ logger = structlog.get_logger(__name__)
@api_view(["GET"])
# @cache_page(60 * 60 * 8, cache="api_page_cache")
@cache_page(60 * 60 * 8, cache="api_page_cache")
def page_api_view(request, slug):
try:
page = Page.objects.get(slug=slug, locale__language_code="de-CH")

View File

@ -40,11 +40,17 @@ class LearningPath(Page):
def __str__(self):
return f"{self.title}"
def get_frontend_url(self):
return f"/learn/{self.slug}"
@classmethod
def get_serializer_class(cls):
return get_it_serializer_class(
cls,
["id", "title", "slug", "type", "translation_key", "children", "course"],
[
"children",
"course",
],
)
@ -76,11 +82,6 @@ class Topic(Page):
return get_it_serializer_class(
cls,
field_names=[
"id",
"title",
"slug",
"type",
"translation_key",
"is_visible",
],
)
@ -143,11 +144,6 @@ class Circle(Page):
return get_it_serializer_class(
cls,
field_names=[
"id",
"title",
"slug",
"type",
"translation_key",
"children",
"description",
"job_situations",
@ -156,6 +152,10 @@ class Circle(Page):
],
)
def get_frontend_url(self):
short_slug = self.slug.replace(f"{self.get_parent().slug}-circle-", "")
return f"{self.get_parent().specific.get_frontend_url()}/{short_slug}"
def full_clean(self, *args, **kwargs):
self.slug = find_slug_with_parent_prefix(self, "circle")
super(Circle, self).full_clean(*args, **kwargs)
@ -185,9 +185,7 @@ class LearningSequence(Page):
@classmethod
def get_serializer_class(cls):
return get_it_serializer_class(
cls, field_names=["id", "title", "slug", "type", "translation_key", "icon"]
)
return get_it_serializer_class(cls, field_names=["icon"])
def get_admin_display_title(self):
return f"{self.icon} {self.draft_title}"
@ -203,6 +201,10 @@ class LearningSequence(Page):
self.slug = find_slug_with_parent_prefix(self, "ls")
super(LearningSequence, self).full_clean(*args, **kwargs)
def get_frontend_url(self):
short_slug = self.slug.replace(f"{self.get_parent().slug}-", "")
return f"{self.get_parent().specific.get_frontend_url()}#{short_slug}"
class LearningUnit(Page):
parent_page_types = ["learnpath.Circle"]
@ -240,6 +242,10 @@ class LearningUnit(Page):
)
super(LearningUnit, self).full_clean(*args, **kwargs)
def get_frontend_url(self):
short_slug = self.slug.replace(f"{self.get_parent().slug}-lu-", "")
return f"{self.get_parent().specific.get_frontend_url()}/evaluate/{short_slug}"
@classmethod
def get_serializer_class(cls):
from vbv_lernwelt.learnpath.serializers import LearningUnitSerializer
@ -298,6 +304,10 @@ class LearningContent(Page):
class Meta:
verbose_name = "Learning Content"
def get_frontend_url(self):
short_slug = self.slug.replace(f"{self.get_parent().slug}-lc-", "")
return f"{self.get_parent().specific.get_frontend_url()}/{short_slug}"
def full_clean(self, *args, **kwargs):
self.slug = find_slug_with_parent_prefix(self, "lc")
super(LearningContent, self).full_clean(*args, **kwargs)
@ -307,11 +317,6 @@ class LearningContent(Page):
return get_it_serializer_class(
cls,
field_names=[
"id",
"title",
"slug",
"type",
"translation_key",
"minutes",
"contents",
],

View File

@ -7,8 +7,19 @@ from vbv_lernwelt.learnpath.utils import get_wagtail_type
def get_it_serializer_class(model, field_names):
base_field_names = [
"id",
"title",
"slug",
"type",
"translation_key",
"frontend_url",
]
return wagtail_serializers.get_serializer_class(
model, field_names=field_names, meta_fields=[], base=ItBaseSerializer
model,
field_names=base_field_names + field_names,
meta_fields=[],
base=ItBaseSerializer,
)
@ -23,6 +34,7 @@ class ItBaseSerializer(wagtail_serializers.BaseSerializer):
children = SerializerMethodField()
course = SerializerMethodField()
course_category = CourseCategorySerializer(read_only=True)
frontend_url = SerializerMethodField()
meta_fields = []
@ -50,6 +62,11 @@ class ItBaseSerializer(wagtail_serializers.BaseSerializer):
return CourseSerializer(course_parent_page.specific.course).data
return ""
def get_frontend_url(self, obj):
if hasattr(obj, "get_frontend_url"):
return obj.get_frontend_url()
return ""
def _get_descendants(pages, obj):
return [c for c in pages if c.path.startswith(obj.path) and c.depth >= obj.depth]

View File

@ -9,11 +9,6 @@ class LearningUnitSerializer(
get_it_serializer_class(
LearningUnit,
[
"id",
"title",
"slug",
"type",
"translation_key",
"course_category",
"children",
],

View File

@ -4,15 +4,15 @@ from vbv_lernwelt.course.consts import COURSE_VERSICHERUNGSVERMITTLERIN_ID
from vbv_lernwelt.course.models import Course, CoursePage
from vbv_lernwelt.media_library.tests.media_library_factories import (
create_external_link_block,
create_internal_link_block,
create_learn_media_block,
create_media_collection,
create_relative_link_block,
ExternalLinkBlockFactory,
InternalLinkBlockFactory,
LearnMediaBlockFactory,
MediaCategoryPageFactory,
MediaLibraryPageFactory,
create_internal_link_block,
InternalLinkBlockFactory,
create_relative_link_block,
RelativeLinkBlockFactory,
)

View File

@ -1,13 +1,13 @@
# Generated by Django 3.2.13 on 2022-10-03 14:18
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import taggit.managers
import wagtail.blocks
import wagtail.fields
import wagtail.models.collections
import wagtail.search.index
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
@ -15,61 +15,395 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('course', '0001_initial'),
("course", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('taggit', '0004_alter_taggeditem_content_type_alter_taggeditem_tag'),
('wagtailcore', '0069_log_entry_jsonfield'),
("taggit", "0004_alter_taggeditem_content_type_alter_taggeditem_tag"),
("wagtailcore", "0069_log_entry_jsonfield"),
]
operations = [
migrations.CreateModel(
name='MediaLibraryPage',
name="MediaLibraryPage",
fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
],
options={
'abstract': False,
"abstract": False,
},
bases=('wagtailcore.page',),
bases=("wagtailcore.page",),
),
migrations.CreateModel(
name='MediaCategoryPage',
name="MediaCategoryPage",
fields=[
('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
('introduction_text', models.TextField(default='')),
('description_title', models.TextField(default='Das erwartet dich in diesem Handlungsfeld')),
('description_text', models.TextField(default='')),
('items', wagtail.fields.StreamField([('item', wagtail.blocks.TextBlock())], use_json_field=True)),
('overview_icon', models.CharField(default='icon-hf-fahrzeug', max_length=255)),
('body', wagtail.fields.StreamField([('content_collection', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock()), ('contents', wagtail.blocks.StreamBlock([('learn_media', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock(blank=False, null=False)), ('description', wagtail.blocks.TextBlock(default='', required=False)), ('icon_url', wagtail.blocks.TextBlock(default='', required=False)), ('link_display_text', wagtail.blocks.CharBlock(default='Link öffnen', max_length=255)), ('url', wagtail.blocks.TextBlock(default='', required=False)), ('open_window', wagtail.blocks.BooleanBlock(default=False)), ('page', wagtail.blocks.PageChooserBlock(page_type=['learnpath.LearningContent'], required=False))])), ('external_link', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock(blank=False, null=False)), ('description', wagtail.blocks.TextBlock(default='', required=False)), ('icon_url', wagtail.blocks.TextBlock(default='', required=False)), ('link_display_text', wagtail.blocks.CharBlock(default='Link öffnen', max_length=255)), ('url', wagtail.blocks.TextBlock(default='', required=False)), ('open_window', wagtail.blocks.BooleanBlock(default=False)), ('page', wagtail.blocks.PageChooserBlock(page_type=['learnpath.LearningContent'], required=False))])), ('internal_link', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock(blank=False, null=False)), ('description', wagtail.blocks.TextBlock(default='', required=False)), ('icon_url', wagtail.blocks.TextBlock(default='', required=False)), ('link_display_text', wagtail.blocks.CharBlock(default='Link öffnen', max_length=255)), ('url', wagtail.blocks.TextBlock(default='', required=False)), ('open_window', wagtail.blocks.BooleanBlock(default=False)), ('page', wagtail.blocks.PageChooserBlock(page_type=['learnpath.LearningContent'], required=False))])), ('relative_link', wagtail.blocks.StructBlock([('title', wagtail.blocks.TextBlock(blank=False, null=False)), ('description', wagtail.blocks.TextBlock(default='', required=False)), ('icon_url', wagtail.blocks.TextBlock(default='', required=False)), ('link_display_text', wagtail.blocks.CharBlock(default='Link öffnen', max_length=255)), ('url', wagtail.blocks.TextBlock(default='', required=False)), ('open_window', wagtail.blocks.BooleanBlock(default=False)), ('page', wagtail.blocks.PageChooserBlock(page_type=['learnpath.LearningContent'], required=False))]))]))]))], null=True, use_json_field=True)),
('course_category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='course.coursecategory')),
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
("introduction_text", models.TextField(default="")),
(
"description_title",
models.TextField(
default="Das erwartet dich in diesem Handlungsfeld"
),
),
("description_text", models.TextField(default="")),
(
"items",
wagtail.fields.StreamField(
[("item", wagtail.blocks.TextBlock())], use_json_field=True
),
),
(
"overview_icon",
models.CharField(default="icon-hf-fahrzeug", max_length=255),
),
(
"body",
wagtail.fields.StreamField(
[
(
"content_collection",
wagtail.blocks.StructBlock(
[
("title", wagtail.blocks.TextBlock()),
(
"contents",
wagtail.blocks.StreamBlock(
[
(
"learn_media",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(
blank=False,
null=False,
),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
(
"external_link",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(
blank=False,
null=False,
),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
(
"internal_link",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(
blank=False,
null=False,
),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
(
"relative_link",
wagtail.blocks.StructBlock(
[
(
"title",
wagtail.blocks.TextBlock(
blank=False,
null=False,
),
),
(
"description",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"icon_url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"link_display_text",
wagtail.blocks.CharBlock(
default="Link öffnen",
max_length=255,
),
),
(
"url",
wagtail.blocks.TextBlock(
default="",
required=False,
),
),
(
"open_window",
wagtail.blocks.BooleanBlock(
default=False
),
),
(
"page",
wagtail.blocks.PageChooserBlock(
page_type=[
"learnpath.LearningContent"
],
required=False,
),
),
]
),
),
]
),
),
]
),
)
],
null=True,
use_json_field=True,
),
),
(
"course_category",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to="course.coursecategory",
),
),
],
options={
'abstract': False,
"abstract": False,
},
bases=('wagtailcore.page',),
bases=("wagtailcore.page",),
),
migrations.CreateModel(
name='LibraryDocument',
name="LibraryDocument",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, verbose_name='title')),
('file', models.FileField(upload_to='documents', verbose_name='file')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')),
('file_size', models.PositiveIntegerField(editable=False, null=True)),
('file_hash', models.CharField(blank=True, editable=False, max_length=40)),
('display_text', models.CharField(default='', max_length=1024)),
('description', models.TextField(default='')),
('link_display_text', models.CharField(default='', max_length=1024)),
('thumbnail', models.URLField()),
('collection', models.ForeignKey(default=wagtail.models.collections.get_root_collection_id, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.collection', verbose_name='collection')),
('tags', taggit.managers.TaggableManager(blank=True, help_text=None, through='taggit.TaggedItem', to='taggit.Tag', verbose_name='tags')),
('uploaded_by_user', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='uploaded by user')),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("title", models.CharField(max_length=255, verbose_name="title")),
("file", models.FileField(upload_to="documents", verbose_name="file")),
(
"created_at",
models.DateTimeField(auto_now_add=True, verbose_name="created at"),
),
("file_size", models.PositiveIntegerField(editable=False, null=True)),
(
"file_hash",
models.CharField(blank=True, editable=False, max_length=40),
),
("display_text", models.CharField(default="", max_length=1024)),
("description", models.TextField(default="")),
("link_display_text", models.CharField(default="", max_length=1024)),
("thumbnail", models.URLField()),
(
"collection",
models.ForeignKey(
default=wagtail.models.collections.get_root_collection_id,
on_delete=django.db.models.deletion.CASCADE,
related_name="+",
to="wagtailcore.collection",
verbose_name="collection",
),
),
(
"tags",
taggit.managers.TaggableManager(
blank=True,
help_text=None,
through="taggit.TaggedItem",
to="taggit.Tag",
verbose_name="tags",
),
),
(
"uploaded_by_user",
models.ForeignKey(
blank=True,
editable=False,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL,
verbose_name="uploaded by user",
),
),
],
options={
'verbose_name': 'document',
'verbose_name_plural': 'documents',
'abstract': False,
"verbose_name": "document",
"verbose_name_plural": "documents",
"abstract": False,
},
bases=(wagtail.search.index.Indexed, models.Model),
),

View File

@ -25,16 +25,14 @@ class MediaLibraryPage(Page):
)
super(MediaLibraryPage, self).full_clean(*args, **kwargs)
def get_frontend_url(self):
return f"/media/{self.slug}"
@classmethod
def get_serializer_class(cls):
return get_it_serializer_class(
cls,
[
"id",
"title",
"slug",
"type",
"translation_key",
"course",
"children",
],
@ -82,20 +80,19 @@ class MediaCategoryPage(Page):
def full_clean(self, *args, **kwargs):
self.slug = find_available_slug(
slugify(f"{self.get_parent()}-cat-{self.title}", allow_unicode=True)
slugify(f"{self.get_parent().slug}-cat-{self.title}", allow_unicode=True)
)
super(MediaCategoryPage, self).full_clean(*args, **kwargs)
def get_frontend_url(self):
short_slug = self.slug.replace(f"{self.get_parent().slug}-cat-", "")
return f"{self.get_parent().specific.get_frontend_url()}/handlungsfelder/{short_slug}"
@classmethod
def get_serializer_class(cls):
return get_it_serializer_class(
cls,
field_names=[
"id",
"title",
"slug",
"type",
"translation_key",
"course_category",
"introduction_text",
"overview_icon",

View File

@ -4,8 +4,8 @@ import wagtail_factories
from vbv_lernwelt.media_library.content_blocks import (
ExternalLinkBlock,
LearnMediaBlock,
InternalLinkBlock,
LearnMediaBlock,
RelativeLinkBlock,
)
from vbv_lernwelt.media_library.models import (