Просмотр исходного кода

Add people section with basic details (#574)

Co-authored-by: Lupyana <lupyana@Lupyanas-MacBook-Pro.local>
Co-authored-by: Thibaud Colas <thibaudcolas@gmail.com>
Lupyana Mbembati 3 недель назад
Родитель
Сommit
c377b468e8

+ 0 - 0
bakerydemo/people/__init__.py


+ 209 - 0
bakerydemo/people/migrations/0001_initial.py

@@ -0,0 +1,209 @@
+# Generated by Django 5.2.7 on 2025-11-12 12:29
+
+import django.db.models.deletion
+import wagtail.fields
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ("wagtailcore", "0095_groupsitepermission"),
+        ("wagtailimages", "0027_image_description"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="PeopleIndexPage",
+            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",
+                    models.TextField(blank=True, help_text="Text to describe the page"),
+                ),
+                (
+                    "image",
+                    models.ForeignKey(
+                        blank=True,
+                        help_text="Landscape mode only; horizontal width between 1000px and 3000px.",
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailimages.image",
+                    ),
+                ),
+            ],
+            options={
+                "abstract": False,
+            },
+            bases=("wagtailcore.page",),
+        ),
+        migrations.CreateModel(
+            name="PersonPage",
+            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",
+                    models.TextField(blank=True, help_text="Text to describe the page"),
+                ),
+                (
+                    "body",
+                    wagtail.fields.StreamField(
+                        [
+                            ("heading_block", 2),
+                            ("paragraph_block", 3),
+                            ("image_block", 6),
+                            ("block_quote", 12),
+                            ("embed_block", 13),
+                        ],
+                        blank=True,
+                        block_lookup={
+                            0: (
+                                "wagtail.blocks.CharBlock",
+                                (),
+                                {"form_classname": "title", "required": True},
+                            ),
+                            1: (
+                                "wagtail.blocks.ChoiceBlock",
+                                [],
+                                {
+                                    "blank": True,
+                                    "choices": [
+                                        ("", "Select a header size"),
+                                        ("h2", "H2"),
+                                        ("h3", "H3"),
+                                        ("h4", "H4"),
+                                    ],
+                                    "required": False,
+                                },
+                            ),
+                            2: (
+                                "wagtail.blocks.StructBlock",
+                                [[("heading_text", 0), ("size", 1)]],
+                                {},
+                            ),
+                            3: (
+                                "wagtail.blocks.RichTextBlock",
+                                (),
+                                {
+                                    "description": "A rich text paragraph",
+                                    "icon": "pilcrow",
+                                    "preview_value": '\n            <h2>Our bread pledge</h2>\n            <p>As a bakery, <b>breads</b> have <i>always</i> been in our hearts.\n            <a href="https://en.wikipedia.org/wiki/Staple_food">Staple foods</a>\n            are essential for society, and – bread is the tastiest of all.\n            We love to transform batters and doughs into baked goods with a firm\n            dry crust and fluffy center.</p>\n            ',
+                                    "template": "blocks/paragraph_block.html",
+                                },
+                            ),
+                            4: (
+                                "wagtail.images.blocks.ImageChooserBlock",
+                                (),
+                                {"required": True},
+                            ),
+                            5: ("wagtail.blocks.CharBlock", (), {"required": False}),
+                            6: (
+                                "wagtail.blocks.StructBlock",
+                                [[("image", 4), ("caption", 5), ("attribution", 5)]],
+                                {},
+                            ),
+                            7: ("wagtail.blocks.TextBlock", (), {}),
+                            8: (
+                                "wagtail.blocks.CharBlock",
+                                (),
+                                {
+                                    "blank": True,
+                                    "label": "e.g. Mary Berry",
+                                    "required": False,
+                                },
+                            ),
+                            9: (
+                                "wagtail.blocks.ChoiceBlock",
+                                [],
+                                {
+                                    "choices": [
+                                        ("default", "Default"),
+                                        ("highlight", "Highlight"),
+                                    ],
+                                    "required": False,
+                                },
+                            ),
+                            10: (
+                                "wagtail.blocks.ChoiceBlock",
+                                [],
+                                {
+                                    "choices": [
+                                        ("default", "Default"),
+                                        ("large", "Large"),
+                                    ],
+                                    "required": False,
+                                },
+                            ),
+                            11: (
+                                "wagtail.blocks.StructBlock",
+                                [[("theme", 9), ("text_size", 10)]],
+                                {"collapsed": True},
+                            ),
+                            12: (
+                                "wagtail.blocks.StructBlock",
+                                [
+                                    [
+                                        ("text", 7),
+                                        ("attribute_name", 8),
+                                        ("settings", 11),
+                                    ]
+                                ],
+                                {},
+                            ),
+                            13: (
+                                "wagtail.embeds.blocks.EmbedBlock",
+                                (),
+                                {
+                                    "description": "An embedded video or other media",
+                                    "help_text": "Insert an embed URL e.g https://www.youtube.com/watch?v=SGJFWirQ3ks",
+                                    "icon": "media",
+                                    "preview_template": "base/preview/static_embed_block.html",
+                                    "preview_value": "https://www.youtube.com/watch?v=mwrGSfiB1Mg",
+                                    "template": "blocks/embed_block.html",
+                                },
+                            ),
+                        },
+                        verbose_name="Page body",
+                    ),
+                ),
+                (
+                    "image",
+                    models.ForeignKey(
+                        blank=True,
+                        help_text="Landscape mode only; horizontal width between 1000px and 3000px.",
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        related_name="+",
+                        to="wagtailimages.image",
+                    ),
+                ),
+            ],
+            options={
+                "abstract": False,
+            },
+            bases=("wagtailcore.page",),
+        ),
+    ]

+ 25 - 0
bakerydemo/people/migrations/0002_personpage_location.py

@@ -0,0 +1,25 @@
+# Generated by Django 5.2.7 on 2025-11-12 13:04
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("breads", "0009_alter_breadpage_body"),
+        ("people", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="personpage",
+            name="location",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.SET_NULL,
+                to="breads.country",
+            ),
+        ),
+    ]

+ 54 - 0
bakerydemo/people/migrations/0003_personpage_social_links.py

@@ -0,0 +1,54 @@
+# Generated by Django 5.2.7 on 2025-11-27 12:15
+
+import wagtail.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("people", "0002_personpage_location"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="personpage",
+            name="social_links",
+            field=wagtail.fields.StreamField(
+                [("social", 2)],
+                blank=True,
+                block_lookup={
+                    0: (
+                        "wagtail.blocks.ChoiceBlock",
+                        [],
+                        {
+                            "choices": [
+                                ("github", "GitHub"),
+                                ("twitter", "Twitter/X"),
+                                ("linkedin", "LinkedIn"),
+                                ("instagram", "Instagram"),
+                                ("facebook", "Facebook"),
+                                ("mastodon", "Mastodon"),
+                                ("website", "Personal Website"),
+                            ],
+                            "help_text": "Select the social media platform",
+                        },
+                    ),
+                    1: (
+                        "wagtail.blocks.URLBlock",
+                        (),
+                        {
+                            "label": "URL",
+                            "help_text": "Full URL to your profile (e.g., https://github.com/username)"
+                        },
+                    ),
+                    2: (
+                        "wagtail.blocks.StructBlock",
+                        [[("platform", 0), ("url", 1)]],
+                        {},
+                    ),
+                },
+                help_text="Add social media profiles",
+            ),
+        ),
+    ]

+ 0 - 0
bakerydemo/people/migrations/__init__.py


+ 189 - 0
bakerydemo/people/models.py

@@ -0,0 +1,189 @@
+from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
+from django.db import models
+from wagtail.admin.panels import FieldPanel
+from wagtail.api import APIField
+from wagtail.blocks import ChoiceBlock, StructBlock, StructValue, URLBlock
+from wagtail.fields import StreamField
+from wagtail.models import Page
+from wagtail.search import index
+
+from bakerydemo.base.blocks import BaseStreamBlock
+
+from ..breads.models import Country
+
+
+class SocialMediaValue(StructValue):
+    def get_platform_label(self):
+        return dict(self.block.child_blocks["platform"].field.choices).get(
+            self["platform"]
+        )
+
+
+class SocialMediaBlock(StructBlock):
+    """
+    Block for social media links
+    """
+
+    platform = ChoiceBlock(
+        choices=[
+            ("github", "GitHub"),
+            ("twitter", "Twitter/X"),
+            ("linkedin", "LinkedIn"),
+            ("instagram", "Instagram"),
+            ("facebook", "Facebook"),
+            ("mastodon", "Mastodon"),
+            ("website", "Personal Website"),
+        ],
+        help_text="Select the social media platform",
+    )
+    url = URLBlock(
+        label="URL",
+        help_text="Full URL to your profile (e.g., https://github.com/username)",
+    )
+
+    class Meta:
+        icon = "link"
+        label = "Social Media Link"
+        value_class = SocialMediaValue
+
+
+class PersonPage(Page):
+    """
+    Detail view for a specific person
+    """
+
+    introduction = models.TextField(help_text="Text to describe the page", blank=True)
+    image = models.ForeignKey(
+        "wagtailimages.Image",
+        null=True,
+        blank=True,
+        on_delete=models.SET_NULL,
+        related_name="+",
+        help_text="Landscape mode only; horizontal width between 1000px and 3000px.",
+    )
+    body = StreamField(BaseStreamBlock(), verbose_name="Page body", blank=True)
+
+    location = models.ForeignKey(
+        Country,
+        on_delete=models.SET_NULL,
+        null=True,
+        blank=True,
+    )
+
+    social_links = StreamField(
+        [("social", SocialMediaBlock())],
+        blank=True,
+        help_text="Add social media profiles",
+    )
+
+    content_panels = Page.content_panels + [
+        FieldPanel("introduction"),
+        FieldPanel("image"),
+        FieldPanel("location"),
+        FieldPanel("body"),
+        FieldPanel("social_links"),
+    ]
+
+    search_fields = Page.search_fields + [
+        index.SearchField("introduction"),
+        index.SearchField("body"),
+    ]
+
+    parent_page_types = ["PeopleIndexPage"]
+
+    api_fields = [
+        APIField("introduction"),
+        APIField("image"),
+        APIField("body"),
+        APIField("location"),
+        APIField("social_links"),
+    ]
+
+    def get_context(self, request):
+        context = super(PersonPage, self).get_context(request)
+
+        platform_block = SocialMediaBlock().child_blocks["platform"]
+        platform_labels = dict(platform_block.field.choices)
+        social_links = [
+            {
+                "platform": link.value["platform"],
+                "label": platform_labels.get(
+                    link.value["platform"], link.value["platform"]
+                ),
+                "url": link.value["url"],
+            }
+            for link in (self.social_links or [])
+        ]
+
+        context["social_links"] = social_links
+
+        return context
+
+
+class PeopleIndexPage(Page):
+    """
+    Index page for people.
+
+    Lists all People objects with pagination.
+    """
+
+    introduction = models.TextField(help_text="Text to describe the page", blank=True)
+    image = models.ForeignKey(
+        "wagtailimages.Image",
+        null=True,
+        blank=True,
+        on_delete=models.SET_NULL,
+        related_name="+",
+        help_text="Landscape mode only; horizontal width between 1000px and 3000px.",
+    )
+
+    content_panels = Page.content_panels + [
+        FieldPanel("introduction"),
+        FieldPanel("image"),
+    ]
+
+    # Can only have PersonPage children
+    subpage_types = ["PersonPage"]
+
+    api_fields = [
+        APIField("introduction"),
+        APIField("image"),
+    ]
+
+    # Returns a queryset of PersonPage objects that are live, that are direct
+    # descendants of this index page with most recent first
+    def get_people(self):
+        return (
+            PersonPage.objects.live()
+            .descendant_of(self)
+            .order_by("-first_published_at")
+        )
+
+    # Allows child objects (e.g. PersonPage objects) to be accessible via the
+    # template
+    def children(self):
+        return self.get_children().specific().live()
+
+    # Pagination for the index page
+    def paginate(self, request, *args):
+        page = request.GET.get("page")
+        paginator = Paginator(self.get_people(), 12)
+        try:
+            pages = paginator.page(page)
+        except PageNotAnInteger:
+            pages = paginator.page(1)
+        except EmptyPage:
+            pages = paginator.page(paginator.num_pages)
+        return pages
+
+    # Returns the above to the get_context method that is used to populate the
+    # template
+    def get_context(self, request):
+        context = super(PeopleIndexPage, self).get_context(request)
+
+        # PersonPage objects (get_people) are passed through pagination
+        people = self.paginate(request, self.get_people())
+
+        context["people"] = people
+
+        return context

+ 1 - 0
bakerydemo/settings/base.py

@@ -77,6 +77,7 @@ INSTALLED_APPS = [
     "django.contrib.messages",
     "django.contrib.staticfiles",
     "django.contrib.sitemaps",
+    "bakerydemo.people",
 ]
 
 MIDDLEWARE = [

+ 26 - 0
bakerydemo/templates/people/people_index_page.html

@@ -0,0 +1,26 @@
+{% extends "base.html" %}
+{% load wagtailcore_tags navigation_tags wagtailimages_tags %}
+
+{% block content %}
+    {% include "base/include/header-index.html" %}
+
+    <div class="container">
+        <ul class="bread-list">
+            {% for person in people %}
+                <li>
+                    {% include "includes/card/listing-card.html" with page=person %}
+                </li>
+            {% endfor %}
+        </ul>
+    </div>
+
+    {% if people.paginator.count > 12 %}
+        <div class="container">
+            <div class="row">
+                <div class="col-sm-12">
+                    {% include "includes/pagination.html" with subpages=people %}
+                </div>
+            </div>
+        </div>
+    {% endif %}
+{% endblock content %}

+ 81 - 0
bakerydemo/templates/people/person_page.html

@@ -0,0 +1,81 @@
+{% extends "base.html" %}
+{% load wagtailimages_tags %}
+
+{% block content %}
+    {% include "base/include/header-hero.html" %}
+
+    <div class="container bread-detail">
+        <div class="row">
+            <div class="col-md-12">
+                <div class="col-md-7">
+                    <div class="row">
+                        {% if page.introduction %}
+                            <p class="bread-detail__introduction">
+                                {{ page.introduction }}
+                            </p>
+                        {% endif %}
+
+                        <div class="hidden-md-down">
+                            {{ page.body }}
+                        </div>
+                    </div>
+                </div>
+
+                <div class="col-md-4 col-md-offset-1">
+                    <div class="row">
+                        <div class="bread-detail__meta">
+                            {% if page.location %}
+                                <p class="bread-detail__meta-title">Location</p>
+                                <p class="bread-detail__meta-content">{{ page.location }}</p>
+                            {% endif %}
+                            {% if page.social_links %}
+                                <p class="bread-detail__meta-title">Socials</p>
+                                <div class="social-links">
+                                    {% for block in page.social_links %}
+                                        <a href="{{ block.value.url }}" target="_blank" rel="noopener noreferrer" title="{{ block.value.get_platform_label }}">
+                                            {% if block.value.platform == 'github' %}
+                                                <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+                                                    <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
+                                                </svg>
+                                            {% elif block.value.platform == 'twitter' %}
+                                                <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+                                                    <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
+                                                </svg>
+                                            {% elif block.value.platform == 'linkedin' %}
+                                                <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+                                                    <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
+                                                </svg>
+                                            {% elif block.value.platform == 'instagram' %}
+                                                <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+                                                    <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678c-3.405 0-6.162 2.76-6.162 6.162 0 3.405 2.76 6.162 6.162 6.162 3.405 0 6.162-2.76 6.162-6.162 0-3.405-2.76-6.162-6.162-6.162zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405c0 .795-.646 1.44-1.44 1.44-.795 0-1.44-.646-1.44-1.44 0-.794.646-1.439 1.44-1.439.793-.001 1.44.645 1.44 1.439z"/>
+                                                </svg>
+                                            {% elif block.value.platform == 'facebook' %}
+                                                <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+                                                    <path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/>
+                                                </svg>
+                                            {% elif block.value.platform == 'mastodon' %}
+                                                <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+                                                    <path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"/>
+                                                </svg>
+                                            {% elif block.value.platform == 'website' %}
+                                                <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+                                                    <path d="M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm1 16.057v-3.057h2.994c-.059 1.143-.212 2.24-.456 3.279-.823-.12-1.674-.188-2.538-.222zm1.957 2.162c-.499 1.33-1.159 2.497-1.957 3.456v-3.62c.666.028 1.319.081 1.957.164zm-1.957-7.219v-3.015c.868-.034 1.721-.103 2.548-.224.238 1.027.389 2.111.446 3.239h-2.994zm0-5.014v-3.661c.806.969 1.471 2.15 1.971 3.496-.642.084-1.3.137-1.971.165zm2.703-3.267c1.237.496 2.354 1.228 3.29 2.146-.642.234-1.311.442-2.019.607-.344-.992-.775-1.91-1.271-2.753zm-7.241 13.56c-.244-1.039-.398-2.136-.456-3.279h2.994v3.057c-.865.034-1.714.102-2.538.222zm2.538 1.776v3.62c-.798-.959-1.458-2.126-1.957-3.456.638-.083 1.291-.136 1.957-.164zm-2.994-7.055c.057-1.128.207-2.212.446-3.239.827.121 1.68.19 2.548.224v3.015h-2.994zm1.024-5.179c.5-1.346 1.165-2.527 1.97-3.496v3.661c-.671-.028-1.329-.081-1.97-.165zm-2.005-.35c-.708-.165-1.377-.373-2.018-.607.937-.918 2.053-1.65 3.29-2.146-.496.844-.927 1.762-1.272 2.753zm-.549 1.918c-.264 1.151-.434 2.36-.492 3.611h-3.933c.165-1.658.739-3.197 1.617-4.518.88.361 1.816.67 2.808.907zm.009 9.262c-.988.236-1.92.542-2.797.9-.89-1.328-1.471-2.879-1.637-4.551h3.934c.058 1.265.231 2.488.5 3.651zm.553 1.917c.342.976.768 1.881 1.257 2.712-1.223-.49-2.326-1.211-3.256-2.115.636-.229 1.299-.435 1.999-.597zm9.924 0c.7.163 1.362.367 1.999.597-.931.903-2.034 1.625-3.257 2.116.489-.832.915-1.737 1.258-2.713zm.553-1.917c.27-1.163.442-2.386.501-3.651h3.934c-.167 1.672-.748 3.223-1.638 4.551-.877-.358-1.81-.664-2.797-.9zm.501-5.651c-.058-1.251-.229-2.46-.492-3.611.992-.237 1.929-.546 2.809-.907.877 1.321 1.451 2.86 1.616 4.518h-3.933z"/>
+                                                </svg>
+                                            {% endif %}
+                                        </a>
+                                    {% endfor %}
+                                </div>
+                            {% endif %}
+                        </div>
+                    </div>
+                </div>
+
+                <div class="col-md-7">
+                    <div class="row hidden-md-up">
+                        {{ page.body }}
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+{% endblock content %}