From d26fbef5a1d1bca20eee361d810fa4638b244373 Mon Sep 17 00:00:00 2001 From: dawnwages Date: Thu, 19 Oct 2023 12:00:26 -0400 Subject: [PATCH 01/88] work in progress - TODO: fix error in block imports --- home/blocks.py | 245 ++++++++++++++++++++++++++++++++++++++ home/models.py | 81 +++++++++++++ indymeet/settings/base.py | 3 + indymeet/settings/dev.py | 9 -- indymeet/urls.py | 3 +- 5 files changed, 331 insertions(+), 10 deletions(-) create mode 100644 home/blocks.py diff --git a/home/blocks.py b/home/blocks.py new file mode 100644 index 00000000..d27b829a --- /dev/null +++ b/home/blocks.py @@ -0,0 +1,245 @@ +from wagtail.core import blocks +from wagtail.images.blocks import ImageChooserBlock + +CODE_LANGUAGE_OPTIONS = ( + ("Python", "python"), + ("Markup", "html"), + ("CSS", "css"), + ("Clojure", "clojure"), + ("Bash", "shell"), + ("Django", "django"), + ("Jinja2", "jinja2"), + ("Docker", "dockerfile"), + ("Git", "git"), + ("GraphQL", "graphql"), + ("Handlebars", "handlebars"), + (".ignore", "gitignore"), + ("JSON", "json"), + ("JSON5", "json5"), + ("Markdown", "md"), + ("Markdown", "md"), + ("React JSX", "jsx"), + ("React TSX", "tsx"), + ("SASS", "sass"), + ("SCSS", "scss"), + ("TypeScript", "ts"), + ("vim", "vim"), +) + + +class HeadingBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="heading-blog") + + def __str__(self): + return self.heading + + class Meta: + template = "blocks/heading.html" + + +class TextWithHeadingBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="heading-blog") + text = blocks.TextBlock() + + def __str__(self): + return self.heading + + class Meta: + label = "Text Block with Header" + template = "blocks/text-with-heading.html" + + +class TextWithHeadingWithRightImageBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="heading-blog") + text = blocks.TextBlock() + image = ImageChooserBlock() + + def __str__(self): + return self.heading + + class Meta: + label = "Text Block with Header: Right Image" + template = "blocks/text-with-heading-right-image.html" + + +class TextWithHeadingWithLeftImageBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="blog") + text = blocks.TextBlock() + image = ImageChooserBlock() + + def __str__(self): + return self.heading + + class Meta: + label = "Text Block with Header: Left Image" + template = "blocks/text-with-heading-left-image.html" + + +class RightImageLeftTextBlock(blocks.StructBlock): + image = ImageChooserBlock() + text = blocks.TextBlock() + + def __str__(self): + return self.text + + class Meta: + label = "Text Block: Right Image" + template = "blocks/right-image-left-text.html" + + +class LeftImageRightTextBlock(blocks.StructBlock): + image = ImageChooserBlock() + text = blocks.TextBlock() + + def __str__(self): + return self.text + + class Meta: + label = "Text Block: Left Image" + template = "blocks/left-image-right-text.html" + + +class QuoteLeftImageBlock(blocks.StructBlock): + quote = blocks.TextBlock() + byline = blocks.CharBlock(max_length=255) + image = ImageChooserBlock() + + def __str__(self): + return self.byline + + class Meta: + template = "blocks/quote-left-image.html" + label = "Person Quote and Image" + form_classname = "Full" + + +class LiteYoutubeEmbed(blocks.StructBlock): + title = blocks.CharBlock(max_length=255, required=False) + border = blocks.CharBlock(max_length=20, required=False) + embed = blocks.CharBlock( + max_length=20, + verbose_name="Youtube Video ID", + help_text="Youtube ID only, example: WGNKjQGYIpg", + ) + + def __str__(self): + return self.title + + class Meta: + template = "blocks/lite-youtube-embed.html" + + +class CodeBlock(blocks.StructBlock): + language = blocks.ChoiceBlock(choices=CODE_LANGUAGE_OPTIONS) + caption = blocks.CharBlock(max_length=255, blank=True) + page = blocks.CharBlock(max_length=255, blank=True) + code = blocks.TextBlock(max_length=1000, blank=True) + + def __str__(self): + return self.caption + + class Meta: + label = "Code Block" + template = "home/blocks/code-block.html" + + +class HeadingBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="heading-blog") + + def __str__(self): + return self.heading + + class Meta: + template = "blocks/heading.html" + + +class TextWithHeadingBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="heading-blog") + text = blocks.TextBlock() + + def __str__(self): + return self.heading + + class Meta: + label = "Text Block with Header" + template = "blocks/text-with-heading.html" + + +class TextWithHeadingWithRightImageBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="heading-blog") + text = blocks.TextBlock() + image = ImageChooserBlock() + + def __str__(self): + return self.heading + + class Meta: + label = "Text Block with Header: Right Image" + template = "blocks/text-with-heading-right-image.html" + + +class TextWithHeadingWithLeftImageBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255, class_name="blog") + text = blocks.TextBlock() + image = ImageChooserBlock() + + def __str__(self): + return self.heading + + class Meta: + label = "Text Block with Header: Left Image" + template = "blocks/text-with-heading-left-image.html" + + +class RightImageLeftTextBlock(blocks.StructBlock): + image = ImageChooserBlock() + text = blocks.TextBlock() + + def __str__(self): + return self.text + + class Meta: + label = "Text Block: Right Image" + template = "blocks/right-image-left-text.html" + + +class LeftImageRightTextBlock(blocks.StructBlock): + image = ImageChooserBlock() + text = blocks.TextBlock() + + def __str__(self): + return self.text + + class Meta: + label = "Text Block: Left Image" + template = "blocks/left-image-right-text.html" + + +class QuoteLeftImageBlock(blocks.StructBlock): + quote = blocks.TextBlock() + byline = blocks.CharBlock(max_length=255) + image = ImageChooserBlock() + + def __str__(self): + return self.byline + + class Meta: + template = "blocks/quote-left-image.html" + label = "Person Quote and Image" + form_classname = "Full" + + +class LiteYoutubeEmbed(blocks.StructBlock): + title = blocks.CharBlock(max_length=255, required=False) + border = blocks.CharBlock(max_length=20, required=False) + embed = blocks.CharBlock( + max_length=20, + verbose_name="Youtube Video ID", + help_text="Youtube ID only, example: WGNKjQGYIpg", + ) + + def __str__(self): + return self.title + + class Meta: + template = "blocks/lite-youtube-embed.html" diff --git a/home/models.py b/home/models.py index 93627502..83fee972 100644 --- a/home/models.py +++ b/home/models.py @@ -18,6 +18,22 @@ from .managers import SessionMembershipQuerySet from home.forms import SignUpPage +# BLOG PUPUT IMPORTS +from puput.abstracts import EntryAbstract +from wagtail.core.fields import StreamField +from . import blocks as blog_blocks +from wagtail.core import blocks +from wagtail.images.blocks import ImageChooserBlock +from wagtail.contrib.table_block.blocks import TableBlock +from wagtail.admin.edit_handlers import ( + FieldPanel, + InlinePanel, + MultiFieldPanel, + StreamFieldPanel, + PageChooserPanel, +) +from wagtail.images.edit_handlers import ImageChooserPanel + def sign_up_forms(context): return { @@ -233,3 +249,68 @@ class Meta: ) role = models.CharField(max_length=64, choices=ROLES, default=DJANGONAUT) objects = models.Manager.from_queryset(SessionMembershipQuerySet)() + + +class EntryAbstract(EntryAbstract): + content = StreamField( + [ + ("heading", blog_blocks.HeadingBlock(class_name="full")), + ("subheading", blocks.CharBlock(class_name="full")), + ("paragraph", blocks.RichTextBlock()), + ("html", blocks.RawHTMLBlock(icon="code", label="Raw HTML")), + ("image", ImageChooserBlock()), + ("text_with_heading", blog_blocks.TextWithHeadingBlock(class_name="full")), + ( + "text_with_heading_and_right_image", + blog_blocks.TextWithHeadingWithRightImageBlock(class_name="full"), + ), + ( + "text_with_heading_and_left_image", + blog_blocks.TextWithHeadingWithLeftImageBlock(class_name="full"), + ), + ( + "right_image_left_text", + blog_blocks.RightImageLeftTextBlock(class_name="full"), + ), + ( + "left_image_right_text", + blog_blocks.LeftImageRightTextBlock(class_name="full"), + ), + ( + "left_quote_right_image", + blog_blocks.QuoteLeftImageBlock(class_name="full"), + ), + ("video_embed", blog_blocks.LiteYoutubeEmbed(class_name="full")), + ("table", TableBlock(class_name="full")), + ("code_block", blog_blocks.CodeBlock(class_name="full")), + ], + blank=True, + null=True, + ) + content_panels = [ + MultiFieldPanel( + [ + FieldPanel("title", classname="title"), + ImageChooserPanel("header_image"), + FieldPanel("body", classname="full"), + StreamFieldPanel("content"), + FieldPanel("excerpt", classname="full"), + ], + heading=_("Content"), + ), + MultiFieldPanel( + [ + FieldPanel("tags"), + InlinePanel("entry_categories", label=_("Categories")), + InlinePanel( + "related_entrypage_from", + label=_("Related Entries"), + panels=[PageChooserPanel("entrypage_to")], + ), + ], + heading=_("Page Metadata"), + ), + ] + + class Meta: + abstract = True diff --git a/indymeet/settings/base.py b/indymeet/settings/base.py index 55272bd9..52cbe64c 100644 --- a/indymeet/settings/base.py +++ b/indymeet/settings/base.py @@ -193,3 +193,6 @@ DEFAULT_FROM_EMAIL = "contact@djangonaut.space" SERVER_EMAIL = "contact@djangonaut.space" SILENCED_SYSTEM_CHECKS = ["captcha.recaptcha_test_key_error"] + +PUPUT_AS_PLUGIN = True +PUPUT_ENTRY_MODEL = "home.models.EntryAbstract" diff --git a/indymeet/settings/dev.py b/indymeet/settings/dev.py index 4f686fd8..f7a577a6 100644 --- a/indymeet/settings/dev.py +++ b/indymeet/settings/dev.py @@ -9,15 +9,6 @@ load_dotenv() -# SQLite (deprecated) -if os.getenv("ENVIRONMENT") == "dev": - DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": os.path.join(BASE_DIR, "db.sqlite3"), # noqa F405 - } - } - print("----------------------------------") print("----------------------------------") print("DEV") diff --git a/indymeet/urls.py b/indymeet/urls.py index e5ffaaa8..615dead1 100644 --- a/indymeet/urls.py +++ b/indymeet/urls.py @@ -17,7 +17,8 @@ path("search/", search_views.search, name="search"), path("accounts/", include("accounts.urls")), path("", include("home.urls")), - path("content/", include("puput.urls")), + path("comms/", include("puput.urls")), + path("", include(wagtail_urls)), ] From edcc50499d622b0f74caa1ec1df14846ad61f70a Mon Sep 17 00:00:00 2001 From: dawnwages Date: Thu, 19 Oct 2023 21:50:20 -0400 Subject: [PATCH 02/88] fix name of blog entry abstract to remove error --- home/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/home/models.py b/home/models.py index 83fee972..793fef34 100644 --- a/home/models.py +++ b/home/models.py @@ -251,7 +251,7 @@ class Meta: objects = models.Manager.from_queryset(SessionMembershipQuerySet)() -class EntryAbstract(EntryAbstract): +class BlogAbstract(EntryAbstract): content = StreamField( [ ("heading", blog_blocks.HeadingBlock(class_name="full")), From e6376533581dcdba96b9da234b2a3acd3f9f9bb0 Mon Sep 17 00:00:00 2001 From: dawnwages Date: Thu, 19 Oct 2023 22:11:35 -0400 Subject: [PATCH 03/88] fix url structure for blog --- indymeet/urls.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indymeet/urls.py b/indymeet/urls.py index 615dead1..f16a8185 100644 --- a/indymeet/urls.py +++ b/indymeet/urls.py @@ -17,8 +17,7 @@ path("search/", search_views.search, name="search"), path("accounts/", include("accounts.urls")), path("", include("home.urls")), - path("comms/", include("puput.urls")), - path("", include(wagtail_urls)), + path("", include("puput.urls")), ] From 70303fb23703bb956b8c34ad8f9e8fd45d771303 Mon Sep 17 00:00:00 2001 From: dawnwages Date: Thu, 19 Oct 2023 22:54:41 -0400 Subject: [PATCH 04/88] add general page, fix settings for puput entry page, add block elements, add empty block template names --- home/blocks.py | 129 ++-------- ...generalpage_generaltag_generalpage_tags.py | 242 ++++++++++++++++++ home/models.py | 53 +++- indymeet/settings/base.py | 2 +- indymeet/templates/blocks/code-block.html | 0 indymeet/templates/blocks/heading.html | 0 .../blocks/left-image-right-text.html | 0 indymeet/templates/blocks/quote-block.html | 0 .../templates/blocks/quote-left-image.html | 0 .../blocks/right-image-left-text.html | 0 .../templates/blocks/text-image-heading.html | 0 .../blocks/text-with-heading-left-image.html | 0 .../blocks/text-with-heading-right-image.html | 0 .../templates/blocks/text-with-heading.html | 0 indymeet/templates/blocks/video-embed.html | 0 15 files changed, 319 insertions(+), 107 deletions(-) create mode 100644 home/migrations/0017_generalpage_generaltag_generalpage_tags.py create mode 100644 indymeet/templates/blocks/code-block.html create mode 100644 indymeet/templates/blocks/heading.html create mode 100644 indymeet/templates/blocks/left-image-right-text.html create mode 100644 indymeet/templates/blocks/quote-block.html create mode 100644 indymeet/templates/blocks/quote-left-image.html create mode 100644 indymeet/templates/blocks/right-image-left-text.html create mode 100644 indymeet/templates/blocks/text-image-heading.html create mode 100644 indymeet/templates/blocks/text-with-heading-left-image.html create mode 100644 indymeet/templates/blocks/text-with-heading-right-image.html create mode 100644 indymeet/templates/blocks/text-with-heading.html create mode 100644 indymeet/templates/blocks/video-embed.html diff --git a/home/blocks.py b/home/blocks.py index d27b829a..42ce712f 100644 --- a/home/blocks.py +++ b/home/blocks.py @@ -99,6 +99,18 @@ class Meta: template = "blocks/left-image-right-text.html" +class QuoteBlock(blocks.StructBlock): + text = blocks.CharBlock(max_length=255) + attribution = blocks.CharBlock(max_length=255) + + def __str__(self): + return self.attribution + + class Meta: + label = "Quote Block" + template = "blocks/quote-block.html" + + class QuoteLeftImageBlock(blocks.StructBlock): quote = blocks.TextBlock() byline = blocks.CharBlock(max_length=255) @@ -113,20 +125,17 @@ class Meta: form_classname = "Full" -class LiteYoutubeEmbed(blocks.StructBlock): - title = blocks.CharBlock(max_length=255, required=False) - border = blocks.CharBlock(max_length=20, required=False) - embed = blocks.CharBlock( - max_length=20, - verbose_name="Youtube Video ID", - help_text="Youtube ID only, example: WGNKjQGYIpg", - ) +class VideoEmbed(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255) + text = blocks.TextBlock() + # TODO: Add color and embed field def __str__(self): - return self.title + return self.heading class Meta: - template = "blocks/lite-youtube-embed.html" + label = "Video Embed" + template = "blocks/video-embed.html" class CodeBlock(blocks.StructBlock): @@ -140,106 +149,18 @@ def __str__(self): class Meta: label = "Code Block" - template = "home/blocks/code-block.html" - - -class HeadingBlock(blocks.StructBlock): - heading = blocks.CharBlock(max_length=255, class_name="heading-blog") - - def __str__(self): - return self.heading - - class Meta: - template = "blocks/heading.html" - - -class TextWithHeadingBlock(blocks.StructBlock): - heading = blocks.CharBlock(max_length=255, class_name="heading-blog") - text = blocks.TextBlock() + template = "blocks/code-block.html" - def __str__(self): - return self.heading - - class Meta: - label = "Text Block with Header" - template = "blocks/text-with-heading.html" - -class TextWithHeadingWithRightImageBlock(blocks.StructBlock): - heading = blocks.CharBlock(max_length=255, class_name="heading-blog") +class TextHeadingImageBlock(blocks.StructBlock): + heading = blocks.CharBlock(max_length=255) text = blocks.TextBlock() image = ImageChooserBlock() + # TODO: Add left or right side def __str__(self): return self.heading class Meta: - label = "Text Block with Header: Right Image" - template = "blocks/text-with-heading-right-image.html" - - -class TextWithHeadingWithLeftImageBlock(blocks.StructBlock): - heading = blocks.CharBlock(max_length=255, class_name="blog") - text = blocks.TextBlock() - image = ImageChooserBlock() - - def __str__(self): - return self.heading - - class Meta: - label = "Text Block with Header: Left Image" - template = "blocks/text-with-heading-left-image.html" - - -class RightImageLeftTextBlock(blocks.StructBlock): - image = ImageChooserBlock() - text = blocks.TextBlock() - - def __str__(self): - return self.text - - class Meta: - label = "Text Block: Right Image" - template = "blocks/right-image-left-text.html" - - -class LeftImageRightTextBlock(blocks.StructBlock): - image = ImageChooserBlock() - text = blocks.TextBlock() - - def __str__(self): - return self.text - - class Meta: - label = "Text Block: Left Image" - template = "blocks/left-image-right-text.html" - - -class QuoteLeftImageBlock(blocks.StructBlock): - quote = blocks.TextBlock() - byline = blocks.CharBlock(max_length=255) - image = ImageChooserBlock() - - def __str__(self): - return self.byline - - class Meta: - template = "blocks/quote-left-image.html" - label = "Person Quote and Image" - form_classname = "Full" - - -class LiteYoutubeEmbed(blocks.StructBlock): - title = blocks.CharBlock(max_length=255, required=False) - border = blocks.CharBlock(max_length=20, required=False) - embed = blocks.CharBlock( - max_length=20, - verbose_name="Youtube Video ID", - help_text="Youtube ID only, example: WGNKjQGYIpg", - ) - - def __str__(self): - return self.title - - class Meta: - template = "blocks/lite-youtube-embed.html" + label = "Text, Header and Image" + template = "blocks/text-image-heading.html" diff --git a/home/migrations/0017_generalpage_generaltag_generalpage_tags.py b/home/migrations/0017_generalpage_generaltag_generalpage_tags.py new file mode 100644 index 00000000..330f5cd6 --- /dev/null +++ b/home/migrations/0017_generalpage_generaltag_generalpage_tags.py @@ -0,0 +1,242 @@ +# Generated by Django 4.1.5 on 2023-10-20 02:53 + +from django.db import migrations, models +import django.db.models.deletion +import modelcluster.contrib.taggit +import modelcluster.fields +import wagtail.blocks +import wagtail.contrib.table_block.blocks +import wagtail.fields +import wagtail.images.blocks + + +class Migration(migrations.Migration): + dependencies = [ + ("wagtailcore", "0078_referenceindex"), + ("taggit", "0005_auto_20220424_2025"), + ("home", "0016_session_application_end_date_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="GeneralPage", + 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", + ), + ), + ("intro", wagtail.fields.RichTextField(blank=True)), + ("body", wagtail.fields.RichTextField(blank=True)), + ("date", models.DateTimeField(verbose_name="Post Date")), + ( + "content", + wagtail.fields.StreamField( + [ + ( + "heading", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", + max_length=255, + ), + ) + ], + class_name="full", + ), + ), + ("subheading", wagtail.blocks.CharBlock(class_name="full")), + ( + "paragraph", + wagtail.blocks.RichTextBlock(class_name="full"), + ), + ("HTML", wagtail.blocks.RawHTMLBlock(class_name="full")), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "text_with_heading", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", + max_length=255, + ), + ) + ], + class_name="full", + ), + ), + ( + "text_heading_image", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(max_length=255), + ), + ("text", wagtail.blocks.TextBlock()), + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ], + class_name="full", + ), + ), + ( + "video_embed", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(max_length=255), + ), + ("text", wagtail.blocks.TextBlock()), + ], + class_name="full", + ), + ), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + class_name="full" + ), + ), + ( + "code_block", + wagtail.blocks.StructBlock( + [ + ( + "language", + wagtail.blocks.ChoiceBlock( + choices=[ + ("Python", "python"), + ("Markup", "html"), + ("CSS", "css"), + ("Clojure", "clojure"), + ("Bash", "shell"), + ("Django", "django"), + ("Jinja2", "jinja2"), + ("Docker", "dockerfile"), + ("Git", "git"), + ("GraphQL", "graphql"), + ("Handlebars", "handlebars"), + (".ignore", "gitignore"), + ("JSON", "json"), + ("JSON5", "json5"), + ("Markdown", "md"), + ("Markdown", "md"), + ("React JSX", "jsx"), + ("React TSX", "tsx"), + ("SASS", "sass"), + ("SCSS", "scss"), + ("TypeScript", "ts"), + ("vim", "vim"), + ] + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "page", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "code", + wagtail.blocks.TextBlock( + blank=True, max_length=1000 + ), + ), + ], + class_name="full", + ), + ), + ( + "quote_block", + wagtail.blocks.StructBlock( + [ + ( + "text", + wagtail.blocks.CharBlock(max_length=255), + ), + ( + "attribution", + wagtail.blocks.CharBlock(max_length=255), + ), + ], + class_name="full", + ), + ), + ], + blank=True, + null=True, + use_json_field=None, + ), + ), + ], + options={ + "abstract": False, + }, + bases=("wagtailcore.page",), + ), + migrations.CreateModel( + name="GeneralTag", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="tagged_items", + to="home.generalpage", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="%(app_label)s_%(class)s_items", + to="taggit.tag", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.AddField( + model_name="generalpage", + name="tags", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="home.GeneralTag", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + ] diff --git a/home/models.py b/home/models.py index 793fef34..db4c358e 100644 --- a/home/models.py +++ b/home/models.py @@ -7,6 +7,7 @@ from django.urls import reverse from django.utils import timezone from django.utils.translation import gettext_lazy as _ +from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.fields import ParentalKey from modelcluster.models import ClusterableModel from taggit.managers import TaggableManager @@ -20,7 +21,7 @@ # BLOG PUPUT IMPORTS from puput.abstracts import EntryAbstract -from wagtail.core.fields import StreamField +from wagtail.core.fields import StreamField, RichTextField from . import blocks as blog_blocks from wagtail.core import blocks from wagtail.images.blocks import ImageChooserBlock @@ -280,7 +281,7 @@ class BlogAbstract(EntryAbstract): "left_quote_right_image", blog_blocks.QuoteLeftImageBlock(class_name="full"), ), - ("video_embed", blog_blocks.LiteYoutubeEmbed(class_name="full")), + ("video_embed", blog_blocks.VideoEmbed(class_name="full")), ("table", TableBlock(class_name="full")), ("code_block", blog_blocks.CodeBlock(class_name="full")), ], @@ -314,3 +315,51 @@ class BlogAbstract(EntryAbstract): class Meta: abstract = True + + +class GeneralTag(TaggedItemBase): + content_object = ParentalKey( + "GeneralPage", + related_name="tagged_items", + on_delete=models.CASCADE, + ) + + +class GeneralPage(Page): + intro = RichTextField(blank=True) + body = RichTextField(blank=True) + tags = ClusterTaggableManager(through=GeneralTag, blank=True) + date = models.DateTimeField("Post Date") + content = StreamField( + [ + ("heading", blog_blocks.HeadingBlock(class_name="full")), + ("subheading", blocks.CharBlock(class_name="full")), + ("paragraph", blocks.RichTextBlock(class_name="full")), + ("HTML", blocks.RawHTMLBlock(class_name="full")), + ("image", ImageChooserBlock()), + ("text_with_heading", blog_blocks.HeadingBlock(class_name="full")), + ( + "text_heading_image", + blog_blocks.TextHeadingImageBlock(class_name="full"), + ), + ("video_embed", blog_blocks.VideoEmbed(class_name="full")), + ("table", TableBlock(class_name="full")), + ("code_block", blog_blocks.CodeBlock(class_name="full")), + ("quote_block", blog_blocks.QuoteBlock(class_name="full")), + ], + blank=True, + null=True, + ) + + content_panels = Page.content_panels + [ + MultiFieldPanel( + [ + FieldPanel("date"), + FieldPanel("tags"), + ], + heading="Page Information", + ), + FieldPanel("intro"), + FieldPanel("body"), + StreamFieldPanel("content"), + ] diff --git a/indymeet/settings/base.py b/indymeet/settings/base.py index 52cbe64c..7bf912c0 100644 --- a/indymeet/settings/base.py +++ b/indymeet/settings/base.py @@ -195,4 +195,4 @@ SILENCED_SYSTEM_CHECKS = ["captcha.recaptcha_test_key_error"] PUPUT_AS_PLUGIN = True -PUPUT_ENTRY_MODEL = "home.models.EntryAbstract" +PUPUT_ENTRY_MODEL = "home.models.BlogAbstract" diff --git a/indymeet/templates/blocks/code-block.html b/indymeet/templates/blocks/code-block.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/heading.html b/indymeet/templates/blocks/heading.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/left-image-right-text.html b/indymeet/templates/blocks/left-image-right-text.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/quote-block.html b/indymeet/templates/blocks/quote-block.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/quote-left-image.html b/indymeet/templates/blocks/quote-left-image.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/right-image-left-text.html b/indymeet/templates/blocks/right-image-left-text.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/text-image-heading.html b/indymeet/templates/blocks/text-image-heading.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/text-with-heading-left-image.html b/indymeet/templates/blocks/text-with-heading-left-image.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/text-with-heading-right-image.html b/indymeet/templates/blocks/text-with-heading-right-image.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/text-with-heading.html b/indymeet/templates/blocks/text-with-heading.html new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/video-embed.html b/indymeet/templates/blocks/video-embed.html new file mode 100644 index 00000000..e69de29b From 96d5505975808a7a095af76a683726fce44eab38 Mon Sep 17 00:00:00 2001 From: dawnwages Date: Tue, 7 Nov 2023 20:20:55 -0500 Subject: [PATCH 05/88] paragraph blog and puput migrations --- .devcontainer/Dockerfile | 60 +++ environment.yml | 6 + home/puput_migrations/0001_initial.py | 549 +++++++++++++++++++++++ home/puput_migrations/__init__.py | 0 indymeet/templates/blocks/paragraph.html | 0 5 files changed, 615 insertions(+) create mode 100644 .devcontainer/Dockerfile create mode 100644 environment.yml create mode 100644 home/puput_migrations/0001_initial.py create mode 100644 home/puput_migrations/__init__.py create mode 100644 indymeet/templates/blocks/paragraph.html diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..df309564 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,60 @@ +# Use an official Python runtime based on Debian 10 "buster" as a parent image. +FROM python:3.8.1-slim-buster + +# Add user that will be used in the container. +RUN useradd wagtail + +# Port used by this container to serve HTTP. +EXPOSE 8000 + +# Set environment variables. +# 1. Force Python stdout and stderr streams to be unbuffered. +# 2. Set PORT variable that is used by Gunicorn. This should match "EXPOSE" +# command. +ENV PYTHONUNBUFFERED=1 \ + PORT=8000 + +# Install system packages required by Wagtail and Django. +RUN apt-get update --yes --quiet && apt-get install --yes --quiet --no-install-recommends \ + build-essential \ + libpq-dev \ + libmariadbclient-dev \ + libjpeg62-turbo-dev \ + zlib1g-dev \ + libwebp-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install the application server. +RUN pip install "gunicorn==20.0.4" + +# Install the project requirements. +COPY requirements.txt / +RUN pip install -r /requirements.txt + +# Use /app folder as a directory where the source code is stored. +WORKDIR /app + +# Set this directory to be owned by the "wagtail" user. This Wagtail project +# uses SQLite, the folder needs to be owned by the user that +# will be writing to the database file. +RUN chown wagtail:wagtail /app + +# Copy the source code of the project into the container. +COPY --chown=wagtail:wagtail . . + +# Use user "wagtail" to run the build commands below and the server itself. +USER wagtail + +# Collect static files. +RUN python manage.py collectstatic --noinput --clear + +# Runtime command that executes when "docker run" is called, it does the +# following: +# 1. Migrate the database. +# 2. Start the application server. +# WARNING: +# Migrating database at the same time as starting the server IS NOT THE BEST +# PRACTICE. The database should be migrated manually or using the release +# phase facilities of your hosting platform. This is used only so the +# Wagtail instance can be started with a simple "docker run" command. +CMD set -xe; python manage.py migrate --noinput; gunicorn indymeet.wsgi:application diff --git a/environment.yml b/environment.yml new file mode 100644 index 00000000..3047deaf --- /dev/null +++ b/environment.yml @@ -0,0 +1,6 @@ +dependencies: + - jupyter + - matplotlib + - numpy + - psycopg2 + - pylint diff --git a/home/puput_migrations/0001_initial.py b/home/puput_migrations/0001_initial.py new file mode 100644 index 00000000..02219d23 --- /dev/null +++ b/home/puput_migrations/0001_initial.py @@ -0,0 +1,549 @@ +# Generated by Django 4.1.5 on 2023-10-22 06:50 + +import colorful.fields +import datetime +from django.db import migrations, models +import django.db.models.deletion +import django.db.models.manager +import modelcluster.contrib.taggit +import modelcluster.fields +import puput.routes +import wagtail.blocks +import wagtail.contrib.table_block.blocks +import wagtail.embeds.blocks +import wagtail.fields +import wagtail.images.blocks + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("wagtailcore", "0078_referenceindex"), + ("taggit", "0005_auto_20220424_2025"), + ("wagtailimages", "0024_index_image_file_hash"), + ] + + operations = [ + migrations.CreateModel( + name="Category", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.CharField( + max_length=80, unique=True, verbose_name="Category name" + ), + ), + ("slug", models.SlugField(max_length=80, unique=True)), + ( + "description", + models.CharField( + blank=True, max_length=500, verbose_name="Description" + ), + ), + ( + "parent", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="children", + to="puput.category", + verbose_name="Parent category", + ), + ), + ], + options={ + "verbose_name": "Category", + "verbose_name_plural": "Categories", + "ordering": ["name"], + }, + ), + migrations.CreateModel( + name="CategoryEntryPage", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "category", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="puput.category", + verbose_name="Category", + ), + ), + ], + ), + migrations.CreateModel( + name="EntryPage", + 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", + ), + ), + ("body", wagtail.fields.RichTextField(verbose_name="body")), + ( + "date", + models.DateTimeField( + default=datetime.datetime.today, verbose_name="Post date" + ), + ), + ( + "excerpt", + wagtail.fields.RichTextField( + blank=True, + help_text="Entry excerpt to be displayed on entries list. If this field is not filled, a truncate version of body text will be used.", + verbose_name="excerpt", + ), + ), + ("num_comments", models.IntegerField(default=0, editable=False)), + ( + "body_detail", + wagtail.fields.StreamField( + [ + ( + "heading_block", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", + max_length=255, + ), + ) + ] + ), + ), + ("subheading_block", wagtail.blocks.CharBlock()), + ( + "paragraph_block", + wagtail.blocks.RichTextBlock( + icon="pilcrow", template="blocks/paragraph.html" + ), + ), + ( + "html_block", + wagtail.blocks.RawHTMLBlock( + icon="code", label="Raw HTML" + ), + ), + ("image_block", wagtail.images.blocks.ImageChooserBlock()), + ( + "text_with_heading", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", + max_length=255, + ), + ), + ("text", wagtail.blocks.TextBlock()), + ] + ), + ), + ( + "text_with_heading_with_right_image", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", + max_length=255, + ), + ), + ("text", wagtail.blocks.TextBlock()), + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ] + ), + ), + ( + "text_with_heading_with_left_image", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="blog", max_length=255 + ), + ), + ("text", wagtail.blocks.TextBlock()), + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ] + ), + ), + ( + "right_image_left_text", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ("text", wagtail.blocks.TextBlock()), + ] + ), + ), + ( + "left_image_right_text", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ("text", wagtail.blocks.TextBlock()), + ] + ), + ), + ( + "left_quote_right_image", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.TextBlock()), + ( + "byline", + wagtail.blocks.CharBlock(max_length=255), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ] + ), + ), + ( + "video_embed", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(max_length=255), + ), + ("text", wagtail.blocks.TextBlock()), + ] + ), + ), + ("embed_block", wagtail.embeds.blocks.EmbedBlock()), + ("table", wagtail.contrib.table_block.blocks.TableBlock()), + ( + "code_block", + wagtail.blocks.StructBlock( + [ + ( + "language", + wagtail.blocks.ChoiceBlock( + choices=[ + ("Python", "python"), + ("Markup", "html"), + ("CSS", "css"), + ("Clojure", "clojure"), + ("Bash", "shell"), + ("Django", "django"), + ("Jinja2", "jinja2"), + ("Docker", "dockerfile"), + ("Git", "git"), + ("GraphQL", "graphql"), + ("Handlebars", "handlebars"), + (".ignore", "gitignore"), + ("JSON", "json"), + ("JSON5", "json5"), + ("Markdown", "md"), + ("Markdown", "md"), + ("React JSX", "jsx"), + ("React TSX", "tsx"), + ("SASS", "sass"), + ("SCSS", "scss"), + ("TypeScript", "ts"), + ("vim", "vim"), + ] + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "page", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "code", + wagtail.blocks.TextBlock( + blank=True, max_length=1000 + ), + ), + ] + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + ( + "categories", + models.ManyToManyField( + blank=True, + through="puput.CategoryEntryPage", + to="puput.category", + ), + ), + ( + "header_image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.image", + verbose_name="Header image", + ), + ), + ], + options={ + "verbose_name": "Entry", + "verbose_name_plural": "Entries", + }, + bases=("wagtailcore.page", models.Model), + ), + migrations.CreateModel( + name="Tag", + fields=[], + options={ + "proxy": True, + "indexes": [], + "constraints": [], + }, + bases=("taggit.tag",), + ), + migrations.CreateModel( + name="TagEntryPage", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "content_object", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="entry_tags", + to="puput.entrypage", + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="%(app_label)s_%(class)s_items", + to="taggit.tag", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="EntryPageRelated", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "entrypage_from", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="related_entrypage_from", + to="puput.entrypage", + verbose_name="Entry", + ), + ), + ( + "entrypage_to", + modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="related_entrypage_to", + to="puput.entrypage", + verbose_name="Entry", + ), + ), + ], + ), + migrations.AddField( + model_name="entrypage", + name="tags", + field=modelcluster.contrib.taggit.ClusterTaggableManager( + blank=True, + help_text="A comma-separated list of tags.", + through="puput.TagEntryPage", + to="taggit.Tag", + verbose_name="Tags", + ), + ), + migrations.AddField( + model_name="categoryentrypage", + name="page", + field=modelcluster.fields.ParentalKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="entry_categories", + to="puput.entrypage", + ), + ), + migrations.CreateModel( + name="BlogPage", + 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", + ), + ), + ( + "description", + models.CharField( + blank=True, + help_text="The blog description that will appear under the title.", + max_length=255, + verbose_name="Description", + ), + ), + ( + "main_color", + colorful.fields.RGBColorField( + default="#4D6AE0", verbose_name="Blog Main Color" + ), + ), + ( + "display_comments", + models.BooleanField(default=False, verbose_name="Display comments"), + ), + ( + "display_categories", + models.BooleanField( + default=True, verbose_name="Display categories" + ), + ), + ( + "display_tags", + models.BooleanField(default=True, verbose_name="Display tags"), + ), + ( + "display_popular_entries", + models.BooleanField( + default=True, verbose_name="Display popular entries" + ), + ), + ( + "display_last_entries", + models.BooleanField( + default=True, verbose_name="Display last entries" + ), + ), + ( + "display_archive", + models.BooleanField(default=True, verbose_name="Display archive"), + ), + ("disqus_api_secret", models.TextField(blank=True)), + ("disqus_shortname", models.CharField(blank=True, max_length=128)), + ( + "num_entries_page", + models.IntegerField(default=5, verbose_name="Entries per page"), + ), + ( + "num_last_entries", + models.IntegerField(default=3, verbose_name="Last entries limit"), + ), + ( + "num_popular_entries", + models.IntegerField( + default=3, verbose_name="Popular entries limit" + ), + ), + ( + "num_tags_entry_header", + models.IntegerField( + default=5, verbose_name="Tags limit entry header" + ), + ), + ( + "short_feed_description", + models.BooleanField( + default=True, verbose_name="Use short description in feeds" + ), + ), + ( + "header_image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.image", + verbose_name="Header image", + ), + ), + ], + options={ + "verbose_name": "Blog", + }, + bases=(puput.routes.BlogRoutes, "wagtailcore.page", models.Model), + managers=[ + ("extra", django.db.models.manager.Manager()), + ], + ), + ] diff --git a/home/puput_migrations/__init__.py b/home/puput_migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/indymeet/templates/blocks/paragraph.html b/indymeet/templates/blocks/paragraph.html new file mode 100644 index 00000000..e69de29b From c25a1792e67fa5d6a1d5a38eda416e4ff41583c1 Mon Sep 17 00:00:00 2001 From: dawnwages Date: Fri, 10 Nov 2023 07:24:41 -0500 Subject: [PATCH 06/88] move puput migrations --- ...entrypage_body_detail_entrypage_content.py | 201 ++++++++++++++++++ indymeet/settings/base.py | 2 + 2 files changed, 203 insertions(+) create mode 100644 home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py diff --git a/home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py b/home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py new file mode 100644 index 00000000..148a8327 --- /dev/null +++ b/home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py @@ -0,0 +1,201 @@ +# Generated by Django 4.1.5 on 2023-11-10 12:04 + +from django.db import migrations +import wagtail.blocks +import wagtail.contrib.table_block.blocks +import wagtail.fields +import wagtail.images.blocks + + +class Migration(migrations.Migration): + dependencies = [ + ("puput", "0001_initial"), + ] + + operations = [ + migrations.RemoveField( + model_name="entrypage", + name="body_detail", + ), + migrations.AddField( + model_name="entrypage", + name="content", + field=wagtail.fields.StreamField( + [ + ( + "heading", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", max_length=255 + ), + ) + ], + class_name="full", + ), + ), + ("subheading", wagtail.blocks.CharBlock(class_name="full")), + ("paragraph", wagtail.blocks.RichTextBlock()), + ( + "html", + wagtail.blocks.RawHTMLBlock(icon="code", label="Raw HTML"), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "text_with_heading", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", max_length=255 + ), + ), + ("text", wagtail.blocks.TextBlock()), + ], + class_name="full", + ), + ), + ( + "text_with_heading_and_right_image", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", max_length=255 + ), + ), + ("text", wagtail.blocks.TextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ], + class_name="full", + ), + ), + ( + "text_with_heading_and_left_image", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="blog", max_length=255 + ), + ), + ("text", wagtail.blocks.TextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ], + class_name="full", + ), + ), + ( + "right_image_left_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("text", wagtail.blocks.TextBlock()), + ], + class_name="full", + ), + ), + ( + "left_image_right_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("text", wagtail.blocks.TextBlock()), + ], + class_name="full", + ), + ), + ( + "left_quote_right_image", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.TextBlock()), + ("byline", wagtail.blocks.CharBlock(max_length=255)), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ], + class_name="full", + ), + ), + ( + "video_embed", + wagtail.blocks.StructBlock( + [ + ("heading", wagtail.blocks.CharBlock(max_length=255)), + ("text", wagtail.blocks.TextBlock()), + ], + class_name="full", + ), + ), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + class_name="full" + ), + ), + ( + "code_block", + wagtail.blocks.StructBlock( + [ + ( + "language", + wagtail.blocks.ChoiceBlock( + choices=[ + ("Python", "python"), + ("Markup", "html"), + ("CSS", "css"), + ("Clojure", "clojure"), + ("Bash", "shell"), + ("Django", "django"), + ("Jinja2", "jinja2"), + ("Docker", "dockerfile"), + ("Git", "git"), + ("GraphQL", "graphql"), + ("Handlebars", "handlebars"), + (".ignore", "gitignore"), + ("JSON", "json"), + ("JSON5", "json5"), + ("Markdown", "md"), + ("Markdown", "md"), + ("React JSX", "jsx"), + ("React TSX", "tsx"), + ("SASS", "sass"), + ("SCSS", "scss"), + ("TypeScript", "ts"), + ("vim", "vim"), + ] + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "page", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "code", + wagtail.blocks.TextBlock( + blank=True, max_length=1000 + ), + ), + ], + class_name="full", + ), + ), + ], + blank=True, + null=True, + use_json_field=None, + ), + ), + ] diff --git a/indymeet/settings/base.py b/indymeet/settings/base.py index 7bf912c0..3acae09f 100644 --- a/indymeet/settings/base.py +++ b/indymeet/settings/base.py @@ -196,3 +196,5 @@ PUPUT_AS_PLUGIN = True PUPUT_ENTRY_MODEL = "home.models.BlogAbstract" + +MIGRATION_MODULES = {"puput": "home.puput_migrations"} From 8b9119f1e26e1eeca266aa433cc596e315cf2bb1 Mon Sep 17 00:00:00 2001 From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Date: Wed, 15 Nov 2023 16:43:28 +0100 Subject: [PATCH 07/88] Update to handle AoE for deadlines. --- home/models.py | 16 ++++++++++------ home/tests/test_models.py | 9 +++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/home/models.py b/home/models.py index a6bf57f9..bd287111 100644 --- a/home/models.py +++ b/home/models.py @@ -1,5 +1,7 @@ from __future__ import annotations +import datetime + from django.conf import settings from django.core.mail import send_mail from django.db import models @@ -14,10 +16,10 @@ from wagtail.models import Page from wagtail.snippets.models import register_snippet -from .managers import EventQuerySet -from .managers import SessionMembershipQuerySet from home.forms import SignUpPage +from .managers import EventQuerySet, SessionMembershipQuerySet + def sign_up_forms(context): return { @@ -195,10 +197,12 @@ def __str__(self): def is_accepting_applications(self): """Determine if the current date is within the application window""" - return ( - self.application_start_date.date() - <= timezone.now().date() - <= self.application_end_date.date() + aoe_early_timezone = datetime.timezone(datetime.timedelta(hours=12)) + aoe_late_timezone = datetime.timezone(datetime.timedelta(hours=-12)) + today_early_aoe = datetime.datetime.now(tz=aoe_early_timezone).date() + today_late_aoe = datetime.datetime.now(tz=aoe_late_timezone).date() + return (self.application_start_date.date() <= today_early_aoe) and ( + today_late_aoe <= self.application_end_date.date() ) def get_absolute_url(self): diff --git a/home/tests/test_models.py b/home/tests/test_models.py index 0d6bac84..fc99dbdd 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -23,6 +23,10 @@ def test_is_accepting_applications(self): with freeze_time("2023-10-15"): self.assertFalse(self.session.is_accepting_applications()) + with freeze_time("2023-10-15 12:00:00"): + # In UTC, so this is the 16th somewhere in the world + self.assertTrue(self.session.is_accepting_applications()) + with freeze_time("2023-10-16"): self.assertTrue(self.session.is_accepting_applications()) @@ -30,4 +34,9 @@ def test_is_accepting_applications(self): self.assertTrue(self.session.is_accepting_applications()) with freeze_time("2023-11-16"): + # In UTC, so is the 15th still somewhere in the world + self.assertTrue(self.session.is_accepting_applications()) + + with freeze_time("2023-11-16 12:00:00"): + # No longer 15th AoE self.assertFalse(self.session.is_accepting_applications()) From cb7f44dcb5f5c8b361976cc121b93a983e436c6a Mon Sep 17 00:00:00 2001 From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> Date: Wed, 15 Nov 2023 17:47:03 +0100 Subject: [PATCH 08/88] Fakes and mocks are gremlins. (#131) --- home/models.py | 4 ++-- home/tests/test_models.py | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/home/models.py b/home/models.py index bd287111..44f8f5b3 100644 --- a/home/models.py +++ b/home/models.py @@ -201,8 +201,8 @@ def is_accepting_applications(self): aoe_late_timezone = datetime.timezone(datetime.timedelta(hours=-12)) today_early_aoe = datetime.datetime.now(tz=aoe_early_timezone).date() today_late_aoe = datetime.datetime.now(tz=aoe_late_timezone).date() - return (self.application_start_date.date() <= today_early_aoe) and ( - today_late_aoe <= self.application_end_date.date() + return (self.application_start_date <= today_early_aoe) and ( + today_late_aoe <= self.application_end_date ) def get_absolute_url(self): diff --git a/home/tests/test_models.py b/home/tests/test_models.py index fc99dbdd..904472c4 100644 --- a/home/tests/test_models.py +++ b/home/tests/test_models.py @@ -10,16 +10,19 @@ class SessionTests(TestCase): @classmethod def setUpTestData(cls): cls.session = Session.objects.create( - start_date=datetime(2024, 1, 15), - end_date=datetime(2024, 3, 11), + start_date=datetime(2024, 1, 15).date(), + end_date=datetime(2024, 3, 11).date(), title="2024 Session 1", slug="2024-session-1", - invitation_date=datetime(2023, 12, 1), - application_start_date=datetime(2023, 10, 16), - application_end_date=datetime(2023, 11, 15), + invitation_date=datetime(2023, 12, 1).date(), + application_start_date=datetime(2023, 10, 16).date(), + application_end_date=datetime(2023, 11, 15).date(), ) def test_is_accepting_applications(self): + # Ensure that the types of fields are from django, not from when I created the object in memory + self.session.refresh_from_db() + with freeze_time("2023-10-15"): self.assertFalse(self.session.is_accepting_applications()) From 88894af9bfdb9ed34438a3a2f907d79c9cf536e9 Mon Sep 17 00:00:00 2001 From: dawnwages Date: Mon, 27 Nov 2023 17:07:44 -0500 Subject: [PATCH 09/88] fix TableBlock issue and move blog StreamField to resuable StreamBlock --- home/blocks.py | 19 ++ home/models.py | 44 +--- home/puput_migrations/0001_initial.py | 38 ++-- ...entrypage_body_detail_entrypage_content.py | 201 ------------------ indymeet/settings/base.py | 1 + 5 files changed, 44 insertions(+), 259 deletions(-) delete mode 100644 home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py diff --git a/home/blocks.py b/home/blocks.py index 42ce712f..ce55256d 100644 --- a/home/blocks.py +++ b/home/blocks.py @@ -1,6 +1,9 @@ from wagtail.core import blocks +from wagtail.contrib.table_block.blocks import TableBlock +from wagtail.blocks import StreamBlock from wagtail.images.blocks import ImageChooserBlock + CODE_LANGUAGE_OPTIONS = ( ("Python", "python"), ("Markup", "html"), @@ -164,3 +167,19 @@ def __str__(self): class Meta: label = "Text, Header and Image" template = "blocks/text-image-heading.html" + + +class BaseStreamBlock(StreamBlock): + heading = HeadingBlock() + paragraph = blocks.CharBlock(max_length=255) + html = blocks.RawHTMLBlock(icon="code", label="Raw HTML") + image = ImageChooserBlock() + text_with_heading = TextHeadingImageBlock() + text_with_heading_and_right_image = TextWithHeadingWithRightImageBlock() + text_with_heading_and_left_image = TextWithHeadingWithLeftImageBlock() + right_image_left_text = RightImageLeftTextBlock() + left_image_right_text = LeftImageRightTextBlock() + left_quote_right_image = QuoteLeftImageBlock() + video_embed = VideoEmbed() + table = TableBlock() + code_block = CodeBlock() diff --git a/home/models.py b/home/models.py index db4c358e..dbad8bcc 100644 --- a/home/models.py +++ b/home/models.py @@ -23,6 +23,7 @@ from puput.abstracts import EntryAbstract from wagtail.core.fields import StreamField, RichTextField from . import blocks as blog_blocks +from .blocks import BaseStreamBlock from wagtail.core import blocks from wagtail.images.blocks import ImageChooserBlock from wagtail.contrib.table_block.blocks import TableBlock @@ -253,48 +254,19 @@ class Meta: class BlogAbstract(EntryAbstract): - content = StreamField( - [ - ("heading", blog_blocks.HeadingBlock(class_name="full")), - ("subheading", blocks.CharBlock(class_name="full")), - ("paragraph", blocks.RichTextBlock()), - ("html", blocks.RawHTMLBlock(icon="code", label="Raw HTML")), - ("image", ImageChooserBlock()), - ("text_with_heading", blog_blocks.TextWithHeadingBlock(class_name="full")), - ( - "text_with_heading_and_right_image", - blog_blocks.TextWithHeadingWithRightImageBlock(class_name="full"), - ), - ( - "text_with_heading_and_left_image", - blog_blocks.TextWithHeadingWithLeftImageBlock(class_name="full"), - ), - ( - "right_image_left_text", - blog_blocks.RightImageLeftTextBlock(class_name="full"), - ), - ( - "left_image_right_text", - blog_blocks.LeftImageRightTextBlock(class_name="full"), - ), - ( - "left_quote_right_image", - blog_blocks.QuoteLeftImageBlock(class_name="full"), - ), - ("video_embed", blog_blocks.VideoEmbed(class_name="full")), - ("table", TableBlock(class_name="full")), - ("code_block", blog_blocks.CodeBlock(class_name="full")), - ], + stream_body = StreamField( + BaseStreamBlock(), + verbose_name="StreamField Body", blank=True, - null=True, + use_json_field=True, ) - content_panels = [ + + content_panels = Page.content_panels + [ MultiFieldPanel( [ FieldPanel("title", classname="title"), ImageChooserPanel("header_image"), - FieldPanel("body", classname="full"), - StreamFieldPanel("content"), + FieldPanel("stream_body"), FieldPanel("excerpt", classname="full"), ], heading=_("Content"), diff --git a/home/puput_migrations/0001_initial.py b/home/puput_migrations/0001_initial.py index 02219d23..ecd40d46 100644 --- a/home/puput_migrations/0001_initial.py +++ b/home/puput_migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.5 on 2023-10-22 06:50 +# Generated by Django 4.1.5 on 2023-11-27 21:19 import colorful.fields import datetime @@ -10,7 +10,6 @@ import puput.routes import wagtail.blocks import wagtail.contrib.table_block.blocks -import wagtail.embeds.blocks import wagtail.fields import wagtail.images.blocks @@ -19,9 +18,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("wagtailcore", "0078_referenceindex"), + ("wagtailcore", "0083_workflowcontenttype"), + ("wagtailimages", "0025_alter_image_file_alter_rendition_file"), ("taggit", "0005_auto_20220424_2025"), - ("wagtailimages", "0024_index_image_file_hash"), ] operations = [ @@ -122,11 +121,11 @@ class Migration(migrations.Migration): ), ("num_comments", models.IntegerField(default=0, editable=False)), ( - "body_detail", + "stream_body", wagtail.fields.StreamField( [ ( - "heading_block", + "heading", wagtail.blocks.StructBlock( [ ( @@ -139,37 +138,32 @@ class Migration(migrations.Migration): ] ), ), - ("subheading_block", wagtail.blocks.CharBlock()), + ("paragraph", wagtail.blocks.CharBlock(max_length=255)), ( - "paragraph_block", - wagtail.blocks.RichTextBlock( - icon="pilcrow", template="blocks/paragraph.html" - ), - ), - ( - "html_block", + "html", wagtail.blocks.RawHTMLBlock( icon="code", label="Raw HTML" ), ), - ("image_block", wagtail.images.blocks.ImageChooserBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), ( "text_with_heading", wagtail.blocks.StructBlock( [ ( "heading", - wagtail.blocks.CharBlock( - class_name="heading-blog", - max_length=255, - ), + wagtail.blocks.CharBlock(max_length=255), ), ("text", wagtail.blocks.TextBlock()), + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), ] ), ), ( - "text_with_heading_with_right_image", + "text_with_heading_and_right_image", wagtail.blocks.StructBlock( [ ( @@ -188,7 +182,7 @@ class Migration(migrations.Migration): ), ), ( - "text_with_heading_with_left_image", + "text_with_heading_and_left_image", wagtail.blocks.StructBlock( [ ( @@ -257,7 +251,6 @@ class Migration(migrations.Migration): ] ), ), - ("embed_block", wagtail.embeds.blocks.EmbedBlock()), ("table", wagtail.contrib.table_block.blocks.TableBlock()), ( "code_block", @@ -316,6 +309,7 @@ class Migration(migrations.Migration): ], blank=True, use_json_field=True, + verbose_name="StreamField Body", ), ), ( diff --git a/home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py b/home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py deleted file mode 100644 index 148a8327..00000000 --- a/home/puput_migrations/0002_remove_entrypage_body_detail_entrypage_content.py +++ /dev/null @@ -1,201 +0,0 @@ -# Generated by Django 4.1.5 on 2023-11-10 12:04 - -from django.db import migrations -import wagtail.blocks -import wagtail.contrib.table_block.blocks -import wagtail.fields -import wagtail.images.blocks - - -class Migration(migrations.Migration): - dependencies = [ - ("puput", "0001_initial"), - ] - - operations = [ - migrations.RemoveField( - model_name="entrypage", - name="body_detail", - ), - migrations.AddField( - model_name="entrypage", - name="content", - field=wagtail.fields.StreamField( - [ - ( - "heading", - wagtail.blocks.StructBlock( - [ - ( - "heading", - wagtail.blocks.CharBlock( - class_name="heading-blog", max_length=255 - ), - ) - ], - class_name="full", - ), - ), - ("subheading", wagtail.blocks.CharBlock(class_name="full")), - ("paragraph", wagtail.blocks.RichTextBlock()), - ( - "html", - wagtail.blocks.RawHTMLBlock(icon="code", label="Raw HTML"), - ), - ("image", wagtail.images.blocks.ImageChooserBlock()), - ( - "text_with_heading", - wagtail.blocks.StructBlock( - [ - ( - "heading", - wagtail.blocks.CharBlock( - class_name="heading-blog", max_length=255 - ), - ), - ("text", wagtail.blocks.TextBlock()), - ], - class_name="full", - ), - ), - ( - "text_with_heading_and_right_image", - wagtail.blocks.StructBlock( - [ - ( - "heading", - wagtail.blocks.CharBlock( - class_name="heading-blog", max_length=255 - ), - ), - ("text", wagtail.blocks.TextBlock()), - ("image", wagtail.images.blocks.ImageChooserBlock()), - ], - class_name="full", - ), - ), - ( - "text_with_heading_and_left_image", - wagtail.blocks.StructBlock( - [ - ( - "heading", - wagtail.blocks.CharBlock( - class_name="blog", max_length=255 - ), - ), - ("text", wagtail.blocks.TextBlock()), - ("image", wagtail.images.blocks.ImageChooserBlock()), - ], - class_name="full", - ), - ), - ( - "right_image_left_text", - wagtail.blocks.StructBlock( - [ - ("image", wagtail.images.blocks.ImageChooserBlock()), - ("text", wagtail.blocks.TextBlock()), - ], - class_name="full", - ), - ), - ( - "left_image_right_text", - wagtail.blocks.StructBlock( - [ - ("image", wagtail.images.blocks.ImageChooserBlock()), - ("text", wagtail.blocks.TextBlock()), - ], - class_name="full", - ), - ), - ( - "left_quote_right_image", - wagtail.blocks.StructBlock( - [ - ("quote", wagtail.blocks.TextBlock()), - ("byline", wagtail.blocks.CharBlock(max_length=255)), - ("image", wagtail.images.blocks.ImageChooserBlock()), - ], - class_name="full", - ), - ), - ( - "video_embed", - wagtail.blocks.StructBlock( - [ - ("heading", wagtail.blocks.CharBlock(max_length=255)), - ("text", wagtail.blocks.TextBlock()), - ], - class_name="full", - ), - ), - ( - "table", - wagtail.contrib.table_block.blocks.TableBlock( - class_name="full" - ), - ), - ( - "code_block", - wagtail.blocks.StructBlock( - [ - ( - "language", - wagtail.blocks.ChoiceBlock( - choices=[ - ("Python", "python"), - ("Markup", "html"), - ("CSS", "css"), - ("Clojure", "clojure"), - ("Bash", "shell"), - ("Django", "django"), - ("Jinja2", "jinja2"), - ("Docker", "dockerfile"), - ("Git", "git"), - ("GraphQL", "graphql"), - ("Handlebars", "handlebars"), - (".ignore", "gitignore"), - ("JSON", "json"), - ("JSON5", "json5"), - ("Markdown", "md"), - ("Markdown", "md"), - ("React JSX", "jsx"), - ("React TSX", "tsx"), - ("SASS", "sass"), - ("SCSS", "scss"), - ("TypeScript", "ts"), - ("vim", "vim"), - ] - ), - ), - ( - "caption", - wagtail.blocks.CharBlock( - blank=True, max_length=255 - ), - ), - ( - "page", - wagtail.blocks.CharBlock( - blank=True, max_length=255 - ), - ), - ( - "code", - wagtail.blocks.TextBlock( - blank=True, max_length=1000 - ), - ), - ], - class_name="full", - ), - ), - ], - blank=True, - null=True, - use_json_field=None, - ), - ), - ] diff --git a/indymeet/settings/base.py b/indymeet/settings/base.py index 3acae09f..7298f96d 100644 --- a/indymeet/settings/base.py +++ b/indymeet/settings/base.py @@ -31,6 +31,7 @@ "captcha", "wagtail.contrib.forms", "wagtail.contrib.redirects", + "wagtail.contrib.table_block", "wagtail.embeds", "wagtail.sites", "wagtail.users", From 2b1ba0ce91746a4a10f40a0808c92513a4a1152c Mon Sep 17 00:00:00 2001 From: dawnwages Date: Mon, 27 Nov 2023 17:25:31 -0500 Subject: [PATCH 10/88] fix migration. prematurely upgraded to 4.2. Not compatible with puput --- home/puput_migrations/0001_initial.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/home/puput_migrations/0001_initial.py b/home/puput_migrations/0001_initial.py index ecd40d46..6acde6df 100644 --- a/home/puput_migrations/0001_initial.py +++ b/home/puput_migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.1.5 on 2023-11-27 21:19 +# Generated by Django 4.1.5 on 2023-11-27 22:22 import colorful.fields import datetime @@ -18,9 +18,9 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ("wagtailcore", "0083_workflowcontenttype"), - ("wagtailimages", "0025_alter_image_file_alter_rendition_file"), ("taggit", "0005_auto_20220424_2025"), + ("wagtailcore", "0078_referenceindex"), + ("wagtailimages", "0024_index_image_file_hash"), ] operations = [ From e2a03d1d35ac8162129bac0a29929cb35657034e Mon Sep 17 00:00:00 2001 From: dawnwages Date: Mon, 4 Dec 2023 08:22:41 -0500 Subject: [PATCH 11/88] update entry page and add templates --- home/models.py | 28 +-- ...rypage_stream_body_alter_entrypage_body.py | 183 ++++++++++++++++++ indymeet/templates/base.html | 1 + indymeet/templates/blocks/code-block.html | 5 + indymeet/templates/blocks/heading.html | 1 + .../blocks/left-image-right-text.html | 9 + indymeet/templates/blocks/paragraph.html | 2 + indymeet/templates/blocks/quote-block.html | 9 + .../templates/blocks/quote-left-image.html | 13 ++ .../blocks/right-image-left-text.html | 8 + .../templates/blocks/text-image-heading.html | 0 .../blocks/text-with-heading-left-image.html | 9 + .../blocks/text-with-heading-right-image.html | 9 + .../templates/blocks/text-with-heading.html | 6 + indymeet/templates/blocks/video-embed.html | 13 ++ indymeet/templates/puput/blog_page.html | 4 +- 16 files changed, 272 insertions(+), 28 deletions(-) create mode 100644 home/puput_migrations/0002_remove_entrypage_stream_body_alter_entrypage_body.py delete mode 100644 indymeet/templates/blocks/text-image-heading.html diff --git a/home/models.py b/home/models.py index c127aab2..122dde8b 100644 --- a/home/models.py +++ b/home/models.py @@ -38,7 +38,6 @@ from .managers import EventQuerySet, SessionMembershipQuerySet - def sign_up_forms(context): return { "sign_up_forms": SignUpPage.objects.all(), @@ -258,36 +257,13 @@ class Meta: class BlogAbstract(EntryAbstract): - stream_body = StreamField( + body = StreamField( BaseStreamBlock(), verbose_name="StreamField Body", - blank=True, use_json_field=True, ) - content_panels = Page.content_panels + [ - MultiFieldPanel( - [ - FieldPanel("title", classname="title"), - ImageChooserPanel("header_image"), - FieldPanel("stream_body"), - FieldPanel("excerpt", classname="full"), - ], - heading=_("Content"), - ), - MultiFieldPanel( - [ - FieldPanel("tags"), - InlinePanel("entry_categories", label=_("Categories")), - InlinePanel( - "related_entrypage_from", - label=_("Related Entries"), - panels=[PageChooserPanel("entrypage_to")], - ), - ], - heading=_("Page Metadata"), - ), - ] + content_panels = EntryAbstract.content_panels + [] class Meta: abstract = True diff --git a/home/puput_migrations/0002_remove_entrypage_stream_body_alter_entrypage_body.py b/home/puput_migrations/0002_remove_entrypage_stream_body_alter_entrypage_body.py new file mode 100644 index 00000000..bc968c23 --- /dev/null +++ b/home/puput_migrations/0002_remove_entrypage_stream_body_alter_entrypage_body.py @@ -0,0 +1,183 @@ +# Generated by Django 4.1.5 on 2023-11-27 22:52 + +from django.db import migrations +import wagtail.blocks +import wagtail.contrib.table_block.blocks +import wagtail.fields +import wagtail.images.blocks + + +class Migration(migrations.Migration): + dependencies = [ + ("puput", "0001_initial"), + ] + + operations = [ + migrations.RemoveField( + model_name="entrypage", + name="stream_body", + ), + migrations.AlterField( + model_name="entrypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "heading", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", max_length=255 + ), + ) + ] + ), + ), + ("paragraph", wagtail.blocks.CharBlock(max_length=255)), + ( + "html", + wagtail.blocks.RawHTMLBlock(icon="code", label="Raw HTML"), + ), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "text_with_heading", + wagtail.blocks.StructBlock( + [ + ("heading", wagtail.blocks.CharBlock(max_length=255)), + ("text", wagtail.blocks.TextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ( + "text_with_heading_and_right_image", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="heading-blog", max_length=255 + ), + ), + ("text", wagtail.blocks.TextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ( + "text_with_heading_and_left_image", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + class_name="blog", max_length=255 + ), + ), + ("text", wagtail.blocks.TextBlock()), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ( + "right_image_left_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("text", wagtail.blocks.TextBlock()), + ] + ), + ), + ( + "left_image_right_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ("text", wagtail.blocks.TextBlock()), + ] + ), + ), + ( + "left_quote_right_image", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.TextBlock()), + ("byline", wagtail.blocks.CharBlock(max_length=255)), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ] + ), + ), + ( + "video_embed", + wagtail.blocks.StructBlock( + [ + ("heading", wagtail.blocks.CharBlock(max_length=255)), + ("text", wagtail.blocks.TextBlock()), + ] + ), + ), + ("table", wagtail.contrib.table_block.blocks.TableBlock()), + ( + "code_block", + wagtail.blocks.StructBlock( + [ + ( + "language", + wagtail.blocks.ChoiceBlock( + choices=[ + ("Python", "python"), + ("Markup", "html"), + ("CSS", "css"), + ("Clojure", "clojure"), + ("Bash", "shell"), + ("Django", "django"), + ("Jinja2", "jinja2"), + ("Docker", "dockerfile"), + ("Git", "git"), + ("GraphQL", "graphql"), + ("Handlebars", "handlebars"), + (".ignore", "gitignore"), + ("JSON", "json"), + ("JSON5", "json5"), + ("Markdown", "md"), + ("Markdown", "md"), + ("React JSX", "jsx"), + ("React TSX", "tsx"), + ("SASS", "sass"), + ("SCSS", "scss"), + ("TypeScript", "ts"), + ("vim", "vim"), + ] + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "page", + wagtail.blocks.CharBlock( + blank=True, max_length=255 + ), + ), + ( + "code", + wagtail.blocks.TextBlock( + blank=True, max_length=1000 + ), + ), + ] + ), + ), + ], + blank=True, + null=True, + use_json_field=True, + verbose_name="StreamField Body", + ), + ), + ] diff --git a/indymeet/templates/base.html b/indymeet/templates/base.html index 0fc8135c..cf42ac65 100644 --- a/indymeet/templates/base.html +++ b/indymeet/templates/base.html @@ -81,6 +81,7 @@ + diff --git a/indymeet/templates/blocks/code-block.html b/indymeet/templates/blocks/code-block.html index e69de29b..f2c1f5b1 100644 --- a/indymeet/templates/blocks/code-block.html +++ b/indymeet/templates/blocks/code-block.html @@ -0,0 +1,5 @@ +
{{ value.page }}
+
+    {{ value.code }}
+
+{{ value.caption }} \ No newline at end of file diff --git a/indymeet/templates/blocks/heading.html b/indymeet/templates/blocks/heading.html index e69de29b..e559d591 100644 --- a/indymeet/templates/blocks/heading.html +++ b/indymeet/templates/blocks/heading.html @@ -0,0 +1 @@ +

{{ value.heading|safe }}

\ No newline at end of file diff --git a/indymeet/templates/blocks/left-image-right-text.html b/indymeet/templates/blocks/left-image-right-text.html index e69de29b..62856499 100644 --- a/indymeet/templates/blocks/left-image-right-text.html +++ b/indymeet/templates/blocks/left-image-right-text.html @@ -0,0 +1,9 @@ +{% load wagtailimages_tags %} + +
+
+
{% image value.image width-1000 %}
+
{{ value.text|safe }}
+
+
+ \ No newline at end of file diff --git a/indymeet/templates/blocks/paragraph.html b/indymeet/templates/blocks/paragraph.html index e69de29b..b39df09c 100644 --- a/indymeet/templates/blocks/paragraph.html +++ b/indymeet/templates/blocks/paragraph.html @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/indymeet/templates/blocks/quote-block.html b/indymeet/templates/blocks/quote-block.html index e69de29b..6465c8e6 100644 --- a/indymeet/templates/blocks/quote-block.html +++ b/indymeet/templates/blocks/quote-block.html @@ -0,0 +1,9 @@ +
+
+
+

{{ value.quote|safe }}

+
—{{ value.byline }}
+
+
+ +
diff --git a/indymeet/templates/blocks/quote-left-image.html b/indymeet/templates/blocks/quote-left-image.html index e69de29b..063040c7 100644 --- a/indymeet/templates/blocks/quote-left-image.html +++ b/indymeet/templates/blocks/quote-left-image.html @@ -0,0 +1,13 @@ +{% load wagtailimages_tags %} + +
+
+
{% image value.image fill-600x600-c50 %}
+
+
+

{{ value.quote|safe }}

+
—{{ value.byline }}
+
+
+
+
diff --git a/indymeet/templates/blocks/right-image-left-text.html b/indymeet/templates/blocks/right-image-left-text.html index e69de29b..b0e47d4c 100644 --- a/indymeet/templates/blocks/right-image-left-text.html +++ b/indymeet/templates/blocks/right-image-left-text.html @@ -0,0 +1,8 @@ +{% load wagtailimages_tags %} + +
+
+
{{ value.text|safe }}
+
{% image value.image width-1000 %}
+
+
diff --git a/indymeet/templates/blocks/text-image-heading.html b/indymeet/templates/blocks/text-image-heading.html deleted file mode 100644 index e69de29b..00000000 diff --git a/indymeet/templates/blocks/text-with-heading-left-image.html b/indymeet/templates/blocks/text-with-heading-left-image.html index e69de29b..3de7ab89 100644 --- a/indymeet/templates/blocks/text-with-heading-left-image.html +++ b/indymeet/templates/blocks/text-with-heading-left-image.html @@ -0,0 +1,9 @@ +{% load wagtailimages_tags %} + +
+

{{ value.heading|safe }}

+
+
{% image value.image width-1000 %}
+
{{ value.text|safe }}
+
+
diff --git a/indymeet/templates/blocks/text-with-heading-right-image.html b/indymeet/templates/blocks/text-with-heading-right-image.html index e69de29b..c517f18e 100644 --- a/indymeet/templates/blocks/text-with-heading-right-image.html +++ b/indymeet/templates/blocks/text-with-heading-right-image.html @@ -0,0 +1,9 @@ +{% load wagtailimages_tags %} + +
+

{{ value.heading|safe }}

+
+
{{ value.text|safe }}
+
{% image value.image width-1000 %}
+
+
diff --git a/indymeet/templates/blocks/text-with-heading.html b/indymeet/templates/blocks/text-with-heading.html index e69de29b..0e1fdb6f 100644 --- a/indymeet/templates/blocks/text-with-heading.html +++ b/indymeet/templates/blocks/text-with-heading.html @@ -0,0 +1,6 @@ +
+

{{ value.heading }}

+
+ {{ value.text|safe }} +
+
diff --git a/indymeet/templates/blocks/video-embed.html b/indymeet/templates/blocks/video-embed.html index e69de29b..5990c581 100644 --- a/indymeet/templates/blocks/video-embed.html +++ b/indymeet/templates/blocks/video-embed.html @@ -0,0 +1,13 @@ + +{% if value.title %}

{{ value.title }}

{% endif %} + +{% if value.embed %} + + {% with "https://www.youtube.com/embed/"|add:value.embed as video_url %} + + {% endwith %} +{% endif %} diff --git a/indymeet/templates/puput/blog_page.html b/indymeet/templates/puput/blog_page.html index 8610a667..6efc1d66 100644 --- a/indymeet/templates/puput/blog_page.html +++ b/indymeet/templates/puput/blog_page.html @@ -70,9 +70,9 @@
{% include 'puput/entry_page_header.html' %} {% if entry.excerpt %} - {{ entry.excerpt|richtext }} + {{ entry.excerpt }} {% else %} - {{ entry.body|richtext|truncatewords_html:70 }} + {{ entry.body|truncatewords_html:70 }} {% endif %}
+ diff --git a/indymeet/templates/blocks/quote-left-image.html b/indymeet/templates/blocks/quote-left-image.html new file mode 100644 index 00000000..063040c7 --- /dev/null +++ b/indymeet/templates/blocks/quote-left-image.html @@ -0,0 +1,13 @@ +{% load wagtailimages_tags %} + +
+
+
{% image value.image fill-600x600-c50 %}
+
+
+

{{ value.quote|safe }}

+
—{{ value.byline }}
+
+
+
+
diff --git a/indymeet/templates/blocks/right-image-left-text.html b/indymeet/templates/blocks/right-image-left-text.html new file mode 100644 index 00000000..b0e47d4c --- /dev/null +++ b/indymeet/templates/blocks/right-image-left-text.html @@ -0,0 +1,8 @@ +{% load wagtailimages_tags %} + +
+
+
{{ value.text|safe }}
+
{% image value.image width-1000 %}
+
+
diff --git a/indymeet/templates/blocks/text-with-heading-left-image.html b/indymeet/templates/blocks/text-with-heading-left-image.html new file mode 100644 index 00000000..3de7ab89 --- /dev/null +++ b/indymeet/templates/blocks/text-with-heading-left-image.html @@ -0,0 +1,9 @@ +{% load wagtailimages_tags %} + +
+

{{ value.heading|safe }}

+
+
{% image value.image width-1000 %}
+
{{ value.text|safe }}
+
+
diff --git a/indymeet/templates/blocks/text-with-heading-right-image.html b/indymeet/templates/blocks/text-with-heading-right-image.html new file mode 100644 index 00000000..c517f18e --- /dev/null +++ b/indymeet/templates/blocks/text-with-heading-right-image.html @@ -0,0 +1,9 @@ +{% load wagtailimages_tags %} + +
+

{{ value.heading|safe }}

+
+
{{ value.text|safe }}
+
{% image value.image width-1000 %}
+
+
diff --git a/indymeet/templates/blocks/text-with-heading.html b/indymeet/templates/blocks/text-with-heading.html new file mode 100644 index 00000000..0e1fdb6f --- /dev/null +++ b/indymeet/templates/blocks/text-with-heading.html @@ -0,0 +1,6 @@ +
+

{{ value.heading }}

+
+ {{ value.text|safe }} +
+
diff --git a/indymeet/templates/blocks/video-embed.html b/indymeet/templates/blocks/video-embed.html new file mode 100644 index 00000000..5990c581 --- /dev/null +++ b/indymeet/templates/blocks/video-embed.html @@ -0,0 +1,13 @@ + +{% if value.title %}

{{ value.title }}

{% endif %} + +{% if value.embed %} + + {% with "https://www.youtube.com/embed/"|add:value.embed as video_url %} + + {% endwith %} +{% endif %} diff --git a/indymeet/templates/puput/blog_page.html b/indymeet/templates/puput/blog_page.html index 8610a667..6efc1d66 100644 --- a/indymeet/templates/puput/blog_page.html +++ b/indymeet/templates/puput/blog_page.html @@ -70,9 +70,9 @@
{% include 'puput/entry_page_header.html' %} {% if entry.excerpt %} - {{ entry.excerpt|richtext }} + {{ entry.excerpt }} {% else %} - {{ entry.body|richtext|truncatewords_html:70 }} + {{ entry.body|truncatewords_html:70 }} {% endif %} @@ -91,6 +95,13 @@ {% trans "Sessions" %} + {% for item in menu_items %} +
  • + + {{ item.text }} + +
  • + {% endfor %}
    From a8fa21c674676415152188954306517eb63e06be Mon Sep 17 00:00:00 2001 From: Dawn Wages Date: Tue, 9 Jan 2024 22:28:44 -0500 Subject: [PATCH 86/88] Add blog link to the pages. (#180) This means we're going to need a comms page in wagtail. Co-authored-by: tschilling --- home/templates/home/home_page.html | 4 +--- indymeet/templates/includes/nav.html | 12 ++++-------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/home/templates/home/home_page.html b/home/templates/home/home_page.html index 2fc51c60..225933c8 100644 --- a/home/templates/home/home_page.html +++ b/home/templates/home/home_page.html @@ -14,9 +14,7 @@

    W Sessions Events Program - {% for item in menu_items %} - {{ item.text }} - {% endfor %} + Blog {% comment %} diff --git a/indymeet/templates/includes/nav.html b/indymeet/templates/includes/nav.html index 50ef7f80..1f53c5cd 100644 --- a/indymeet/templates/includes/nav.html +++ b/indymeet/templates/includes/nav.html @@ -28,13 +28,11 @@ {% trans "Sessions" %} - {% for item in menu_items %}
  • - - {{ item.text }} + + {% trans "Blog" %}
  • - {% endfor %} @@ -95,13 +93,11 @@ {% trans "Sessions" %} - {% for item in menu_items %}
  • - - {{ item.text }} + + {% trans "Blog" %}
  • - {% endfor %} From 4e9695adb9109f66c0afe02258494fc596b592bb Mon Sep 17 00:00:00 2001 From: Sarah Abderemane Date: Wed, 10 Jan 2024 09:25:49 +0100 Subject: [PATCH 87/88] Fix landing page (#182) The class on the homepage was the bootstrap one, and add margin on top and bottom of the buttons to avoid them all being stuck together --- home/templates/home/home_page.html | 4 ++-- theme/static_src/src/djangonaut-space.css | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/home/templates/home/home_page.html b/home/templates/home/home_page.html index b5465aaa..727ddb12 100644 --- a/home/templates/home/home_page.html +++ b/home/templates/home/home_page.html @@ -10,8 +10,8 @@

    Where contributors launch

    Ready for take-off?

    -