Blogcard multiple topics (#8859)
* now rendering published date on blog card * now rendering published date on blog card * card now rendering multiple topics * rendering all topics instead of just the first * newlines * spacing * validation for selecting two topics maximum * updated widget and help text * formatting * updated validation to use clean, removed unnecesary changes * formatting * formatting * formatting * formatting * validation using a custom form * feedback from PR * feedback from PR, updated comment * flake * Update network-api/networkapi/wagtailpages/forms.py Co-authored-by: Tibor Leupold <tiborl@mozillafoundation.org> * updated comment and formatting Co-authored-by: Tibor Leupold <tiborl@mozillafoundation.org>
This commit is contained in:
Родитель
cd7492137f
Коммит
5f2f3e7806
|
@ -1,4 +1,4 @@
|
|||
from wagtail.admin.forms import WagtailAdminModelForm
|
||||
from wagtail.admin.forms import WagtailAdminModelForm, WagtailAdminPageForm
|
||||
|
||||
|
||||
class BuyersGuideProductCategoryForm(WagtailAdminModelForm):
|
||||
|
@ -24,3 +24,18 @@ class BuyersGuideProductCategoryForm(WagtailAdminModelForm):
|
|||
if self.instance == parent:
|
||||
self.add_error("parent", "A category cannot be a parent of itself.")
|
||||
return parent
|
||||
|
||||
|
||||
# Max number validation for blog page topics. We are using a custom form to avoid
|
||||
# an issue where the `ValidationError` raised in the page's `clean` method is
|
||||
# not caught by Wagtail. Instead of displaying the `ValidationError` as a message to
|
||||
# the editor, the admin crashes with a 500 error. Using the custom form gets around
|
||||
# that issue.
|
||||
class BlogPageForm(WagtailAdminPageForm):
|
||||
def clean(self):
|
||||
cleaned_data = super(BlogPageForm, self).clean()
|
||||
topics = cleaned_data['topics']
|
||||
if topics.count() > 2:
|
||||
self.add_error('topics', 'Please select 2 topics max.')
|
||||
|
||||
return cleaned_data
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 3.2.13 on 2022-06-03 22:53
|
||||
|
||||
from django.db import migrations
|
||||
import modelcluster.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wagtailpages', '0027_rename_blogpagecategory_blogpagetopic_rename_categoryfilter_topicfilter'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='blogpage',
|
||||
name='topics',
|
||||
field=modelcluster.fields.ParentalManyToManyField(blank=True, help_text='Which blog topics is this blog page associated with? Please select 2 topics max.', to='wagtailpages.BlogPageTopic', verbose_name='Topics'),
|
||||
),
|
||||
]
|
|
@ -2,6 +2,8 @@ from django.db import models
|
|||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.template.defaultfilters import truncatechars
|
||||
from django.forms import CheckboxSelectMultiple
|
||||
|
||||
from wagtail.admin.edit_handlers import (
|
||||
FieldPanel,
|
||||
InlinePanel,
|
||||
|
@ -17,7 +19,6 @@ from wagtail.core.fields import StreamField
|
|||
from wagtail.core.rich_text import get_text_for_indexing
|
||||
from wagtail.snippets.edit_handlers import SnippetChooserPanel
|
||||
from wagtail.images.edit_handlers import ImageChooserPanel
|
||||
|
||||
from wagtail_localize.fields import TranslatableField, SynchronizedField
|
||||
|
||||
from taggit.models import TaggedItemBase
|
||||
|
@ -26,7 +27,6 @@ from modelcluster.contrib.taggit import ClusterTaggableManager
|
|||
from .. import customblocks
|
||||
from ..customblocks.full_content_rich_text_options import full_content_rich_text_options
|
||||
|
||||
|
||||
from ..mixin.foundation_metadata import FoundationMetadataPageMixin
|
||||
|
||||
from ...utils import (
|
||||
|
@ -36,6 +36,7 @@ from ...utils import (
|
|||
)
|
||||
|
||||
from networkapi.wagtailpages.models import Profile
|
||||
from networkapi.wagtailpages.forms import BlogPageForm
|
||||
from .blog_topic import BlogPageTopic
|
||||
from .blog_index import BlogIndexPage
|
||||
|
||||
|
@ -120,7 +121,7 @@ class BlogPage(FoundationMetadataPageMixin, Page):
|
|||
|
||||
topics = ParentalManyToManyField(
|
||||
BlogPageTopic,
|
||||
help_text='Which blog topics is this blog page associated with?',
|
||||
help_text='Which blog topics is this blog page associated with? Please select 2 topics max.',
|
||||
blank=True,
|
||||
verbose_name='Topics',
|
||||
)
|
||||
|
@ -152,6 +153,9 @@ class BlogPage(FoundationMetadataPageMixin, Page):
|
|||
|
||||
related_post_count = 3
|
||||
|
||||
# Custom base form for topic count validation
|
||||
base_form_class = BlogPageForm
|
||||
|
||||
content_panels = [
|
||||
FieldPanel(
|
||||
'title',
|
||||
|
@ -164,7 +168,7 @@ class BlogPage(FoundationMetadataPageMixin, Page):
|
|||
],
|
||||
heading='Author(s)'
|
||||
),
|
||||
FieldPanel('topics'),
|
||||
FieldPanel('topics', widget=CheckboxSelectMultiple),
|
||||
MultiFieldPanel(
|
||||
[
|
||||
FieldPanel("hero_video"),
|
||||
|
|
|
@ -12,13 +12,16 @@ crawls up the ancestor tree until it has found it.
|
|||
each blog page's dominant tag)
|
||||
|
||||
{% block tags %}
|
||||
{% with topic=page.specific.topics.first %}
|
||||
{% if topic %}
|
||||
{% with topics=page.specific.topics.all %}
|
||||
{% for topic in topics %}
|
||||
{% localized_version topic as localized_topic %}
|
||||
{% get_root_or_page as parent_page %}
|
||||
{# If we have a "root" context variable, we know this card is generated on an index page (or index page subroute) #}
|
||||
<a class="tw-h6-heading tw-mb-0" href="{% localizedroutablepageurl parent_page "entries_by_topic" topic.slug %}">{{ localized_topic }}</a>
|
||||
{% endif %}
|
||||
{# If we have a "root" context variable, we know this card is generated on an index page (or index page subroute) #}
|
||||
<a class="tw-h6-heading tw-mb-0 tw-text-blue-80" href="{% localizedroutablepageurl parent_page "entries_by_topic" topic.slug %}">{{ localized_topic }}</a>
|
||||
{% if not forloop.last %}
|
||||
<span class="tw-h6-heading tw-text-blue-80"> / </span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ module.exports = {
|
|||
...typePlugins,
|
||||
...glyphPlugins,
|
||||
require("@tailwindcss/forms")({ strategy: "class" }),
|
||||
require('@tailwindcss/line-clamp'),
|
||||
require("@tailwindcss/line-clamp"),
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
|
|
Загрузка…
Ссылка в новой задаче