From 6fd74833a32a48bb58f0944cf1c283d53d4fefb0 Mon Sep 17 00:00:00 2001 From: Konstantin Kostov Date: Fri, 1 Mar 2024 11:55:17 +0100 Subject: [PATCH] feat: add footer, header and improve layout --- base/__init__.py | 0 base/admin.py | 3 + base/apps.py | 6 ++ base/migrations/0001_initial.py | 26 +++++++ base/migrations/0002_footertext.py | 42 +++++++++++ base/migrations/__init__.py | 0 base/models.py | 65 +++++++++++++++++ base/templates/base/includes/footer_text.html | 5 ++ base/templatetags/__init__.py | 0 base/templatetags/navigation_tags.py | 23 ++++++ base/tests.py | 3 + base/views.py | 3 + iamkonstantin_web/settings/base.py | 3 + .../static/css/iamkonstantin_web.css | 45 ++++++++++++ iamkonstantin_web/templates/base.html | 71 +++++++++++-------- .../templates/includes/footer.html | 24 +++++++ .../templates/includes/header.html | 16 +++++ 17 files changed, 305 insertions(+), 30 deletions(-) create mode 100644 base/__init__.py create mode 100644 base/admin.py create mode 100644 base/apps.py create mode 100644 base/migrations/0001_initial.py create mode 100644 base/migrations/0002_footertext.py create mode 100644 base/migrations/__init__.py create mode 100644 base/models.py create mode 100644 base/templates/base/includes/footer_text.html create mode 100644 base/templatetags/__init__.py create mode 100644 base/templatetags/navigation_tags.py create mode 100644 base/tests.py create mode 100644 base/views.py create mode 100644 iamkonstantin_web/templates/includes/footer.html create mode 100644 iamkonstantin_web/templates/includes/header.html diff --git a/base/__init__.py b/base/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/base/admin.py b/base/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/base/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/base/apps.py b/base/apps.py new file mode 100644 index 0000000..05011e8 --- /dev/null +++ b/base/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BaseConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'base' diff --git a/base/migrations/0001_initial.py b/base/migrations/0001_initial.py new file mode 100644 index 0000000..a94e2b1 --- /dev/null +++ b/base/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.2 on 2024-02-29 20:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='NavigationSettings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('linkedin_url', models.URLField(blank=True, verbose_name='LinkedIn URL')), + ('github_url', models.URLField(blank=True, verbose_name='GitHub URL')), + ('mastodon_url', models.URLField(blank=True, verbose_name='Mastodon URL')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/base/migrations/0002_footertext.py b/base/migrations/0002_footertext.py new file mode 100644 index 0000000..0ec4bac --- /dev/null +++ b/base/migrations/0002_footertext.py @@ -0,0 +1,42 @@ +# Generated by Django 5.0.2 on 2024-02-29 21:00 + +import django.db.models.deletion +import uuid +import wagtail.fields +import wagtail.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('base', '0001_initial'), + ('wagtailcore', '0091_remove_revision_submitted_for_moderation'), + ] + + operations = [ + migrations.CreateModel( + name='FooterText', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('translation_key', models.UUIDField(default=uuid.uuid4, editable=False)), + ('live', models.BooleanField(default=True, editable=False, verbose_name='live')), + ('has_unpublished_changes', models.BooleanField(default=False, editable=False, verbose_name='has unpublished changes')), + ('first_published_at', models.DateTimeField(blank=True, db_index=True, null=True, verbose_name='first published at')), + ('last_published_at', models.DateTimeField(editable=False, null=True, verbose_name='last published at')), + ('go_live_at', models.DateTimeField(blank=True, null=True, verbose_name='go live date/time')), + ('expire_at', models.DateTimeField(blank=True, null=True, verbose_name='expiry date/time')), + ('expired', models.BooleanField(default=False, editable=False, verbose_name='expired')), + ('body', wagtail.fields.RichTextField()), + ('latest_revision', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.revision', verbose_name='latest revision')), + ('live_revision', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.revision', verbose_name='live revision')), + ('locale', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='wagtailcore.locale')), + ], + options={ + 'verbose_name_plural': 'Footer Text', + 'abstract': False, + 'unique_together': {('translation_key', 'locale')}, + }, + bases=(wagtail.models.PreviewableMixin, models.Model), + ), + ] diff --git a/base/migrations/__init__.py b/base/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/base/models.py b/base/models.py new file mode 100644 index 0000000..460f541 --- /dev/null +++ b/base/models.py @@ -0,0 +1,65 @@ +from django.db import models +from modelcluster.models import ClusterableModel +from wagtail.admin.panels import ( + FieldPanel, + MultiFieldPanel, + PublishingPanel +) +from wagtail.fields import RichTextField +from wagtail.models import ( + DraftStateMixin, + PreviewableMixin, + RevisionMixin, + TranslatableMixin, +) +from wagtail.snippets.models import register_snippet + +from wagtail.contrib.settings.models import ( + BaseGenericSetting, + register_setting, +) + +@register_setting +class NavigationSettings(BaseGenericSetting): + linkedin_url = models.URLField(verbose_name="LinkedIn URL", blank=True) + github_url = models.URLField(verbose_name="GitHub URL", blank=True) + mastodon_url = models.URLField(verbose_name="Mastodon URL", blank=True) + + panels = [ + MultiFieldPanel( + [ + FieldPanel("linkedin_url"), + FieldPanel("github_url"), + FieldPanel("mastodon_url"), + ], + "Social settings", + ) + ] + +@register_snippet +class FooterText( + DraftStateMixin, + RevisionMixin, + PreviewableMixin, + TranslatableMixin, + models.Model, +): + + body = RichTextField() + + panels = [ + FieldPanel("body"), + PublishingPanel(), + ] + + def __str__(self): + return "Footer text" + + def get_preview_template(self, request, mode_name): + return "base.html" + + def get_preview_context(self, request, mode_name): + return {"footer_text": self.body} + + class Meta(TranslatableMixin.Meta): + verbose_name_plural = "Footer Text" \ No newline at end of file diff --git a/base/templates/base/includes/footer_text.html b/base/templates/base/includes/footer_text.html new file mode 100644 index 0000000..2dec019 --- /dev/null +++ b/base/templates/base/includes/footer_text.html @@ -0,0 +1,5 @@ +{% load wagtailcore_tags %} + +
+ {{ footer_text|richtext }} +
\ No newline at end of file diff --git a/base/templatetags/__init__.py b/base/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/base/templatetags/navigation_tags.py b/base/templatetags/navigation_tags.py new file mode 100644 index 0000000..01af89d --- /dev/null +++ b/base/templatetags/navigation_tags.py @@ -0,0 +1,23 @@ +from django import template +from wagtail.models import Site +from base.models import FooterText + +register = template.Library() + + +@register.inclusion_tag("base/includes/footer_text.html", takes_context=True) +def get_footer_text(context): + footer_text = context.get("footer_text", "") + + if not footer_text: + instance = FooterText.objects.filter(live=True).first() + footer_text = instance.body if instance else "" + + return { + "footer_text": footer_text, + } + + +@register.simple_tag(takes_context=True) +def get_site_root(context): + return Site.find_for_request(context["request"]).root_page diff --git a/base/tests.py b/base/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/base/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/base/views.py b/base/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/base/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/iamkonstantin_web/settings/base.py b/iamkonstantin_web/settings/base.py index 777adc7..4df5c76 100644 --- a/iamkonstantin_web/settings/base.py +++ b/iamkonstantin_web/settings/base.py @@ -24,9 +24,11 @@ BASE_DIR = os.path.dirname(PROJECT_DIR) # Application definition INSTALLED_APPS = [ + "base", "blog", "home", "search", + "wagtail.contrib.settings", "wagtail.contrib.forms", "wagtail.contrib.redirects", "wagtail.embeds", @@ -74,6 +76,7 @@ TEMPLATES = [ "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", + "wagtail.contrib.settings.context_processors.settings" ], }, }, diff --git a/iamkonstantin_web/static/css/iamkonstantin_web.css b/iamkonstantin_web/static/css/iamkonstantin_web.css index e69de29..ee65db9 100644 --- a/iamkonstantin_web/static/css/iamkonstantin_web.css +++ b/iamkonstantin_web/static/css/iamkonstantin_web.css @@ -0,0 +1,45 @@ +*, +::before, +::after { + box-sizing: border-box; +} + +html { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif, Apple Color Emoji, "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} + +body { + min-height: 100vh; + max-width: 800px; + margin: 0 auto; + padding: 10px; + display: grid; + gap: 3vw; + grid-template-rows: min-content 1fr min-content; +} + +a { + color: currentColor; +} + +footer { + border-top: 2px dotted; + text-align: center; +} + +header { + border-bottom: 2px dotted; +} + +.template-homepage main { + text-align: center; +} + +.skip-link { + position: absolute; + top: -30px; +} + +.skip-link:focus-visible { + top: 5px; +} \ No newline at end of file diff --git a/iamkonstantin_web/templates/base.html b/iamkonstantin_web/templates/base.html index cb95df5..3b91b65 100644 --- a/iamkonstantin_web/templates/base.html +++ b/iamkonstantin_web/templates/base.html @@ -1,46 +1,57 @@ -{% load static wagtailcore_tags wagtailuserbar %} +{% load static wagtailcore_tags %} - - - - {% block title %} +<head> + <meta charset="utf-8"/> + <title> + {% block title %} {% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title }}{% endif %} - {% endblock %} - {% block title_suffix %} + {% endblock %} + {% block title_suffix %} {% wagtail_site as current_site %} {% if current_site and current_site.site_name %}- {{ current_site.site_name }}{% endif %} - {% endblock %} - - {% if page.search_description %} - - {% endif %} - + {% endblock %} + + {% if page.search_description %} + + {% endif %} + - {# Force all links in the live preview panel to be opened in a new tab #} - {% if request.in_preview_panel %} + {# Force all links in the live preview panel to be opened in a new tab #} + {% if request.in_preview_panel %} - {% endif %} + {% endif %} - {# Global stylesheets #} - + - {% block extra_css %} + + + + {# Global stylesheets #} + + + {% block extra_css %} {# Override this in templates to add extra stylesheets #} - {% endblock %} - + {% endblock %} + - - {% wagtailuserbar %} + - {% block content %}{% endblock %} +{% include "includes/header.html" %} - {# Global javascript #} - +
+{% block content %}{% endblock %} +
- {% block extra_js %} - {# Override this in templates to add extra javascript #} - {% endblock %} - +{% include "includes/footer.html" %} + +{# Global javascript #} + + +{% block extra_js %} + {# Override this in templates to add extra javascript #} +{% endblock %} + diff --git a/iamkonstantin_web/templates/includes/footer.html b/iamkonstantin_web/templates/includes/footer.html new file mode 100644 index 0000000..3f805bc --- /dev/null +++ b/iamkonstantin_web/templates/includes/footer.html @@ -0,0 +1,24 @@ +{% load navigation_tags %} + + \ No newline at end of file diff --git a/iamkonstantin_web/templates/includes/header.html b/iamkonstantin_web/templates/includes/header.html new file mode 100644 index 0000000..8eeb78a --- /dev/null +++ b/iamkonstantin_web/templates/includes/header.html @@ -0,0 +1,16 @@ +{% load wagtailcore_tags navigation_tags wagtailuserbar %} +
+ {# Add this: #} + + + {% get_site_root as site_root %} + + {% wagtailuserbar "top-right" %} +
\ No newline at end of file