diff --git a/.gitignore b/.gitignore index 1f30251..8833c3d 100644 --- a/.gitignore +++ b/.gitignore @@ -165,4 +165,7 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ -.env.production \ No newline at end of file +.env.production + +media/images/ +media/original_images/ \ No newline at end of file diff --git a/.idea/iamkonstantin-web.iml b/.idea/iamkonstantin-web.iml index 79d7ae9..2d23290 100644 --- a/.idea/iamkonstantin-web.iml +++ b/.idea/iamkonstantin-web.iml @@ -17,7 +17,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index 6de942c..2a30ec5 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..ecefe3a --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +python 3.12.8 diff --git a/Makefile b/Makefile index 9fc9251..aa1009d 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,9 @@ -.PHONY: help build publish -VERSION = 1.5.0 +.PHONY: help bump publish +VERSION = 1.9.15 help: @perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -build: - @docker build -t code.headbright.be/konstantin/iamkonstantin:$(VERSION) . - publish: # something to try: --provenance=false @docker buildx build -t code.headbright.be/konstantin/iamkonstantin:$(VERSION) --platform linux/arm64 --push . diff --git a/base/blocks.py b/base/blocks.py index a109031..aef8178 100644 --- a/base/blocks.py +++ b/base/blocks.py @@ -1,3 +1,4 @@ +from wagtail.api import APIField from wagtail.blocks import ( CharBlock, ChoiceBlock, @@ -14,6 +15,13 @@ class ImageBlock(StructBlock): caption = CharBlock(required=False) attribution = CharBlock(required=False) + api_fields = [ + APIField('image'), + # Adds a URL to a rendered thumbnail of the image to the API + APIField('caption'), + APIField('attribution'), + ] + class Meta: icon = "image" template = "base/blocks/image_block.html" diff --git a/base/wagtail_hooks.py b/base/wagtail_hooks.py index 135e5e2..84e328b 100644 --- a/base/wagtail_hooks.py +++ b/base/wagtail_hooks.py @@ -5,6 +5,8 @@ from urllib.parse import urlparse from base.indexnow import get_key import requests +from blog.models import BlogPage + @hooks.register('after_publish_page') def after_publish_page(request, page): @@ -14,6 +16,9 @@ def after_publish_page(request, page): if urlparse(page_url).hostname == "localhost": print("not notifying indexnow for localhost" + get_key() + ", page url: " + page_url) return + if urlparse(page_url).path.endswith("--priv") or urlparse(page_url).path.endswith("--priv/"): + print("not notifying indexnow for blog page --priv") + return session = requests.Session() session.post( "https://api.indexnow.org/indexnow", diff --git a/blog/migrations/0015_remove_blogindexpage_struct_org_actions_and_more.py b/blog/migrations/0015_remove_blogindexpage_struct_org_actions_and_more.py new file mode 100644 index 0000000..f9b57b6 --- /dev/null +++ b/blog/migrations/0015_remove_blogindexpage_struct_org_actions_and_more.py @@ -0,0 +1,218 @@ +# Generated by Django 5.1.6 on 2025-05-06 17:00 + +import django.db.models.deletion +from django.db import migrations, models + +from home.models import HomePage + +STRUCT_ORG_FIELDS = [ + "struct_org_type", + "struct_org_name", + "struct_org_logo_id", + "struct_org_image_id", + "struct_org_phone", + "struct_org_address_street", + "struct_org_address_locality", + "struct_org_address_region", + "struct_org_address_postal", + "struct_org_address_country", + "struct_org_geo_lat", + "struct_org_geo_lng", + "struct_org_hours", + "struct_org_actions", + "struct_org_extra_json", ] +# put here every model names of yours that could have been filled with structured seo data; +# order will matter when searching for pages data +SEO_MODELS = [HomePage] + + +def fill_settings_from_pages_struct_org(apps, schema_editor): + """ + Search for pages where seo struct info was filled and use that to + fill new settings struct data + """ + + SeoSettings = apps.get_model("wagtailseo", "SeoSettings") + Site = apps.get_model("wagtailcore", "Site") + + for site in Site.objects.all().select_related("root_page"): + for model_name in SEO_MODELS: + model = apps.get_model("home", model_name) + page = model.objects.filter( + path__startswith=site.root_page.path, + depth__gte=site.root_page.depth + ).order_by( + 'path' + ).exclude(struct_org_name__exact="").first() + # if you are sure that only root pages were used to fill structured data, + # you can directly use: + # page = site.root_page.specific if site.root_page.specific._meta.model_name in SEO_MODELS else None + if page is not None: + seo_settings, _ = SeoSettings.objects.get_or_create(site=site) + for field in STRUCT_ORG_FIELDS: + setattr(seo_settings, field, getattr(page, field)) + seo_settings.save() + break + + +def fill_pages_from_settings_struct_org(apps, schema_editor): + """ + The reverse migration. + + For every site, find the most top-level page inheriting from SeoMixin + and fill its struct information using the site's settings + """ + SeoSettings = apps.get_model("wagtailseo", "SeoSettings") + for seo_settings in SeoSettings.objects.all().select_related("site", "site__root_page"): + for model_name in SEO_MODELS: + model = apps.get_model("home", model_name) + page = model.objects.filter( + path__startswith=seo_settings.site.root_page.path, + depth__gte=seo_settings.site.root_page.depth + ).order_by('path').first() + if page is not None: + for field in STRUCT_ORG_FIELDS: + setattr(page, field, getattr(seo_settings, field)) + page.save() + break + +class Migration(migrations.Migration): + + dependencies = [ + ('blog', '0014_alter_blogpage_body'), + ('wagtailimages', '0027_image_description'), + ("wagtailseo", "0003_seosettings_struct_org_fields"), + ] + + operations = [ + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_actions', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_address_country', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_address_locality', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_address_postal', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_address_region', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_address_street', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_extra_json', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_geo_lat', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_geo_lng', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_hours', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_image', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_logo', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_name', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_phone', + ), + migrations.RemoveField( + model_name='blogindexpage', + name='struct_org_type', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_actions', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_address_country', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_address_locality', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_address_postal', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_address_region', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_address_street', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_extra_json', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_geo_lat', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_geo_lng', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_hours', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_image', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_logo', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_name', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_phone', + ), + migrations.RemoveField( + model_name='blogpage', + name='struct_org_type', + ), + migrations.AlterField( + model_name='blogindexpage', + name='og_image', + field=models.ForeignKey(blank=True, help_text='Shown when linking to this page on social media. If blank, may show an image from the page, or the default from Settings > SEO.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Preview image'), + ), + migrations.AlterField( + model_name='blogpage', + name='og_image', + field=models.ForeignKey(blank=True, help_text='Shown when linking to this page on social media. If blank, may show an image from the page, or the default from Settings > SEO.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Preview image'), + ), + ] diff --git a/blog/models.py b/blog/models.py index c0279c0..54357fa 100644 --- a/blog/models.py +++ b/blog/models.py @@ -5,6 +5,8 @@ from django.db import models from modelcluster.fields import ParentalKey, ParentalManyToManyField from modelcluster.contrib.taggit import ClusterTaggableManager from taggit.models import TaggedItemBase +from wagtail.api import APIField +from wagtail.images.api.fields import ImageRenditionField from wagtail.models import Page, Orderable from wagtail.fields import RichTextField, StreamField @@ -74,6 +76,14 @@ class BlogPage(SeoMixin, Page): else: return None + # Export fields over the API + api_fields = [ + APIField('gallery_images'), + # Adds a URL to a rendered thumbnail of the image to the API + APIField('body'), + APIField('intro'), + APIField('tags'), + ] search_fields = Page.search_fields + [ index.SearchField('intro'), index.SearchField('body'), @@ -122,6 +132,9 @@ class BlogPageGalleryImage(Orderable): FieldPanel('image'), FieldPanel('caption'), ] + api_fields = [ + APIField('image'), + ] @register_snippet diff --git a/blog/templates/blog/blog_page.html b/blog/templates/blog/blog_page.html index c790824..3ad8acd 100644 --- a/blog/templates/blog/blog_page.html +++ b/blog/templates/blog/blog_page.html @@ -5,7 +5,7 @@ {% block body_class %}template-blogpage{% endblock %} {% block content %} -
+

{{ page.title }}

@@ -54,12 +54,12 @@ {% with tags=page.tags.all %} {% if tags %} -
+

Tags

    {% for tag in tags %} -
  • 🏷️ +
  • 🏷 {{ tag }}
  • {% endfor %} @@ -74,13 +74,9 @@
-
- -
- {% include 'newsletter/snippets/signup_form.html' %} -
{% endblock %} \ No newline at end of file diff --git a/home/migrations/0007_remove_homepage_struct_org_actions_and_more.py b/home/migrations/0007_remove_homepage_struct_org_actions_and_more.py new file mode 100644 index 0000000..1ae5f5c --- /dev/null +++ b/home/migrations/0007_remove_homepage_struct_org_actions_and_more.py @@ -0,0 +1,80 @@ +# Generated by Django 5.1.6 on 2025-05-06 17:00 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('home', '0006_alter_homepage_body'), + ('wagtailimages', '0027_image_description'), + ] + + operations = [ + migrations.RemoveField( + model_name='homepage', + name='struct_org_actions', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_address_country', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_address_locality', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_address_postal', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_address_region', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_address_street', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_extra_json', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_geo_lat', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_geo_lng', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_hours', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_image', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_logo', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_name', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_phone', + ), + migrations.RemoveField( + model_name='homepage', + name='struct_org_type', + ), + migrations.AlterField( + model_name='homepage', + name='og_image', + field=models.ForeignKey(blank=True, help_text='Shown when linking to this page on social media. If blank, may show an image from the page, or the default from Settings > SEO.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Preview image'), + ), + ] diff --git a/home/templates/home/home_page.html b/home/templates/home/home_page.html index 161686a..00ed3b9 100644 --- a/home/templates/home/home_page.html +++ b/home/templates/home/home_page.html @@ -9,13 +9,13 @@ >
- Drawing of my computer desk where we see a computer with an open Terminal + Hero image +
+ Drawing of my computer desk where we see a computer with an open Terminal
         with Elixir code snippets. On the shelf behind we can see programming
         books for Rust, Elixir and JavaScript. The books are arranges vertically
         next to a small flower pot. The flower has big green leaves. A cup of
-        steaming coffee sits on the desk, to the left of the computer. The cup has a Python logo on it.
-      </figcaption>
-        <img src= + steaming coffee sits on the desk, to the left of the computer. The cup has a Python logo on it." />

Hi! I'm Konstantin + alt="waving hand emoji" + src="static/images/waving-hand-sign_1f44b.png" />Hi! I'm Konstantin

@@ -50,7 +50,7 @@ @@ -81,7 +82,4 @@
-
- {% include 'newsletter/snippets/signup_form.html' %} -
{% endblock content %} \ No newline at end of file diff --git a/iamkonstantin_web/api.py b/iamkonstantin_web/api.py new file mode 100644 index 0000000..9415198 --- /dev/null +++ b/iamkonstantin_web/api.py @@ -0,0 +1,15 @@ +from wagtail.api.v2.views import PagesAPIViewSet +from wagtail.api.v2.router import WagtailAPIRouter +from wagtail.images.api.v2.views import ImagesAPIViewSet +from wagtail.documents.api.v2.views import DocumentsAPIViewSet + +# Create the router. "wagtailapi" is the URL namespace +api_router = WagtailAPIRouter('wagtailapi') + +# Add the three endpoints using the "register_endpoint" method. +# The first parameter is the name of the endpoint (such as pages, images). This +# is used in the URL of the endpoint +# The second parameter is the endpoint class that handles the requests +api_router.register_endpoint('pages', PagesAPIViewSet) +api_router.register_endpoint('images', ImagesAPIViewSet) +api_router.register_endpoint('documents', DocumentsAPIViewSet) \ No newline at end of file diff --git a/iamkonstantin_web/settings/base.py b/iamkonstantin_web/settings/base.py index 44ac0f7..a978cde 100644 --- a/iamkonstantin_web/settings/base.py +++ b/iamkonstantin_web/settings/base.py @@ -35,6 +35,7 @@ INSTALLED_APPS = [ "wagtail.contrib.settings", "wagtail.contrib.forms", "wagtail.contrib.redirects", + "wagtail.contrib.simple_translation", "wagtail.embeds", "wagtail.sites", "wagtail.users", @@ -43,6 +44,9 @@ INSTALLED_APPS = [ "wagtail.images", "wagtail.search", "wagtail.admin", + "wagtail.locales", + "wagtail.api.v2", + "rest_framework", "wagtail", "modelcluster", "taggit", @@ -68,6 +72,7 @@ MIDDLEWARE = [ "django.middleware.security.SecurityMiddleware", "wagtail.contrib.redirects.middleware.RedirectMiddleware", "blog.middleware.BlogRedirectMiddleware", + "django.middleware.locale.LocaleMiddleware", "django_browser_reload.middleware.BrowserReloadMiddleware" ] @@ -128,7 +133,7 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/5.0/topics/i18n/ -LANGUAGE_CODE = "en-us" +LANGUAGE_CODE = "en" TIME_ZONE = "UTC" @@ -136,6 +141,18 @@ USE_I18N = True USE_TZ = True +WAGTAIL_I18N_ENABLED = True + +USE_L10N = True # allows dates to be shown in the user's locale + +WAGTAIL_CONTENT_LANGUAGES = LANGUAGES = [ + ('en', "English"), + ('fr', "French"), + ('es', "Spanish"), + ('nl', "Dutch"), +] + +WAGTAILSIMPLETRANSLATION_SYNC_PAGE_TREE = False # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.0/howto/static-files/ @@ -186,6 +203,9 @@ WAGTAILSEARCH_BACKENDS = { # Base URL to use when referring to full URLs within the Wagtail admin backend - # e.g. in notification emails. Don't include '/admin' or a trailing slash WAGTAILADMIN_BASE_URL = "https://iamkonstantin.eu" +WAGTAILAPI_BASE_URL = "https://iamkonstantin.eu" + +WAGTAILAPI_SEARCH_ENABLED = True WAGTAIL_CODE_BLOCK_LANGUAGES = ( ('bash', 'Bash/Shell'), diff --git a/iamkonstantin_web/templates/base.html b/iamkonstantin_web/templates/base.html index 90c1c93..33932cd 100644 --- a/iamkonstantin_web/templates/base.html +++ b/iamkonstantin_web/templates/base.html @@ -4,7 +4,8 @@ - + + {% include "wagtailseo/meta.html" %} {% block title %} @@ -80,5 +81,6 @@ {# Override this in templates to add extra javascript #} {% endblock %} {% include "wagtailseo/struct_data.html" %} +{% include "wagtailseo/struct_org_data.html" %} </body> </html> diff --git a/iamkonstantin_web/templates/includes/header.html b/iamkonstantin_web/templates/includes/header.html index 9df9919..406c2ea 100644 --- a/iamkonstantin_web/templates/includes/header.html +++ b/iamkonstantin_web/templates/includes/header.html @@ -3,7 +3,7 @@ <a href="#main" class="skip-link">Skip to content</a> {% get_site_root as site_root %} - <nav class="w-full flex justify-center my-8"> + <nav class="w-full flex justify-center my-8 main"> <ul class="flex space-x-8"> <li><a href="{% pageurl site_root %}">{{ site_root.title }}</a></li> {% for menuitem in site_root.get_children.live.in_menu %} diff --git a/iamkonstantin_web/urls.py b/iamkonstantin_web/urls.py index d53a50e..4b29694 100644 --- a/iamkonstantin_web/urls.py +++ b/iamkonstantin_web/urls.py @@ -1,4 +1,5 @@ from django.conf import settings +from django.conf.urls.i18n import i18n_patterns from django.urls import include, path from django.contrib import admin from django.views.generic.base import TemplateView @@ -8,6 +9,7 @@ from wagtail import urls as wagtail_urls from wagtail.documents import urls as wagtaildocs_urls from blog.feeds import RssBlogFeed +from iamkonstantin_web.api import api_router from newsletter import views as newsletter_views from search import views as search_views from wagtail.contrib.sitemaps.views import sitemap @@ -25,6 +27,17 @@ urlpatterns = [ path('newsletter/thanks', newsletter_views.thanks, name='thanks') ] +urlpatterns += [ + path('api/v2/', api_router.urls), +] + +# Translatable URLs +# These will be available under a language code prefix. For example /en/search/ +urlpatterns += i18n_patterns( + path("", include(wagtail_urls)), + prefix_default_language=False, +) + if settings.DEBUG: from django.conf.urls.static import static from django.contrib.staticfiles.urls import staticfiles_urlpatterns @@ -34,12 +47,12 @@ if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += path("__reload__/", include("django_browser_reload.urls")), -urlpatterns = urlpatterns + [ - # For anything not caught by a more specific rule above, hand over to - # Wagtail's page serving mechanism. This should be the last pattern in - # the list: - path("", include(wagtail_urls)), - # Alternatively, if you want Wagtail pages to be served from a subpath - # of your site, rather than the site root: - # path("pages/", include(wagtail_urls)), -] +# urlpatterns = urlpatterns + [ +# # For anything not caught by a more specific rule above, hand over to +# # Wagtail's page serving mechanism. This should be the last pattern in +# # the list: +# path("", include(wagtail_urls)), +# # Alternatively, if you want Wagtail pages to be served from a subpath +# # of your site, rather than the site root: +# # path("pages/", include(wagtail_urls)), +# ] diff --git a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.2e16d0ba.fill-160x100.png b/media/images/097d70b8f56ef0dbeaefd4a981ccc510.2e16d0ba.fill-160x100.png deleted file mode 100644 index 53861fa..0000000 Binary files a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.2e16d0ba.fill-160x100.png and /dev/null differ diff --git a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.2e16d0ba.fill-320x240.png b/media/images/097d70b8f56ef0dbeaefd4a981ccc510.2e16d0ba.fill-320x240.png deleted file mode 100644 index a695f88..0000000 Binary files a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.2e16d0ba.fill-320x240.png and /dev/null differ diff --git a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.max-165x165.png b/media/images/097d70b8f56ef0dbeaefd4a981ccc510.max-165x165.png deleted file mode 100644 index 5723675..0000000 Binary files a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.max-165x165.png and /dev/null differ diff --git a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-1600.png b/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-1600.png deleted file mode 100644 index ae99c41..0000000 Binary files a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-1600.png and /dev/null differ diff --git a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-400.png b/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-400.png deleted file mode 100644 index 0586455..0000000 Binary files a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-400.png and /dev/null differ diff --git a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-800.png b/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-800.png deleted file mode 100644 index c79bb07..0000000 Binary files a/media/images/097d70b8f56ef0dbeaefd4a981ccc510.width-800.png and /dev/null differ diff --git a/media/images/_508d3ac3-6905-4b23-b662-a3604050a.2e16d0ba.fill-168x168.jpg b/media/images/_508d3ac3-6905-4b23-b662-a3604050a.2e16d0ba.fill-168x168.jpg deleted file mode 100644 index 9bcd145..0000000 Binary files a/media/images/_508d3ac3-6905-4b23-b662-a3604050a.2e16d0ba.fill-168x168.jpg and /dev/null differ diff --git a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-28x28.jpg b/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-28x28.jpg deleted file mode 100644 index 896ff85..0000000 Binary files a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-28x28.jpg and /dev/null differ diff --git a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-40x60.jpg b/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-40x60.jpg deleted file mode 100644 index ba35712..0000000 Binary files a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-40x60.jpg and /dev/null differ diff --git a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-64x64.jpg b/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-64x64.jpg deleted file mode 100644 index 21e5798..0000000 Binary files a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac8.2e16d0ba.fill-64x64.jpg and /dev/null differ diff --git a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac80.max-165x165.jpg b/media/images/_508d3ac3-6905-4b23-b662-a3604050ac80.max-165x165.jpg deleted file mode 100644 index d363d9c..0000000 Binary files a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac80.max-165x165.jpg and /dev/null differ diff --git a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac80.width-28.jpg b/media/images/_508d3ac3-6905-4b23-b662-a3604050ac80.width-28.jpg deleted file mode 100644 index 896ff85..0000000 Binary files a/media/images/_508d3ac3-6905-4b23-b662-a3604050ac80.width-28.jpg and /dev/null differ diff --git a/media/images/moon_and_planets_design.2e16d0ba.fill-320x240.jpg b/media/images/moon_and_planets_design.2e16d0ba.fill-320x240.jpg deleted file mode 100644 index 87942ed..0000000 Binary files a/media/images/moon_and_planets_design.2e16d0ba.fill-320x240.jpg and /dev/null differ diff --git a/media/images/moon_and_planets_design.2e16d0ba.fill-600x338.jpg b/media/images/moon_and_planets_design.2e16d0ba.fill-600x338.jpg deleted file mode 100644 index 9f8798a..0000000 Binary files a/media/images/moon_and_planets_design.2e16d0ba.fill-600x338.jpg and /dev/null differ diff --git a/media/images/moon_and_planets_design.max-165x165.jpg b/media/images/moon_and_planets_design.max-165x165.jpg deleted file mode 100644 index c290590..0000000 Binary files a/media/images/moon_and_planets_design.max-165x165.jpg and /dev/null differ diff --git a/media/images/moon_and_planets_design.original.jpg b/media/images/moon_and_planets_design.original.jpg deleted file mode 100644 index 074d2c1..0000000 Binary files a/media/images/moon_and_planets_design.original.jpg and /dev/null differ diff --git a/media/images/pexels-life-of-pix-8892.2e16d0ba.fill-480x320.jpg b/media/images/pexels-life-of-pix-8892.2e16d0ba.fill-480x320.jpg deleted file mode 100644 index 7af1a8c..0000000 Binary files a/media/images/pexels-life-of-pix-8892.2e16d0ba.fill-480x320.jpg and /dev/null differ diff --git a/media/images/pexels-life-of-pix-8892.max-165x165.jpg b/media/images/pexels-life-of-pix-8892.max-165x165.jpg deleted file mode 100644 index d5d8705..0000000 Binary files a/media/images/pexels-life-of-pix-8892.max-165x165.jpg and /dev/null differ diff --git a/media/images/pexels-life-of-pix-8892.max-800x600.jpg b/media/images/pexels-life-of-pix-8892.max-800x600.jpg deleted file mode 100644 index 9128c36..0000000 Binary files a/media/images/pexels-life-of-pix-8892.max-800x600.jpg and /dev/null differ diff --git a/media/images/pexels-life-of-pix-8892.width-800.jpg b/media/images/pexels-life-of-pix-8892.width-800.jpg deleted file mode 100644 index 9128c36..0000000 Binary files a/media/images/pexels-life-of-pix-8892.width-800.jpg and /dev/null differ diff --git a/media/original_images/097d70b8f56ef0dbeaefd4a981ccc510.png b/media/original_images/097d70b8f56ef0dbeaefd4a981ccc510.png deleted file mode 100644 index eb1805b..0000000 Binary files a/media/original_images/097d70b8f56ef0dbeaefd4a981ccc510.png and /dev/null differ diff --git a/media/original_images/_508d3ac3-6905-4b23-b662-a3604050ac80.jpeg b/media/original_images/_508d3ac3-6905-4b23-b662-a3604050ac80.jpeg deleted file mode 100644 index 94a9f3a..0000000 Binary files a/media/original_images/_508d3ac3-6905-4b23-b662-a3604050ac80.jpeg and /dev/null differ diff --git a/media/original_images/moon_and_planets_design.jpeg b/media/original_images/moon_and_planets_design.jpeg deleted file mode 100644 index d0c1440..0000000 Binary files a/media/original_images/moon_and_planets_design.jpeg and /dev/null differ diff --git a/media/original_images/pexels-life-of-pix-8892.jpg b/media/original_images/pexels-life-of-pix-8892.jpg deleted file mode 100644 index 22e38e6..0000000 Binary files a/media/original_images/pexels-life-of-pix-8892.jpg and /dev/null differ diff --git a/newsletter/templates/newsletter/snippets/signup_form.html b/newsletter/templates/newsletter/snippets/signup_form.html index 500fc82..1b44eb3 100644 --- a/newsletter/templates/newsletter/snippets/signup_form.html +++ b/newsletter/templates/newsletter/snippets/signup_form.html @@ -1,4 +1,4 @@ <div class="py-16 sm:py-24 lg:py-32"> - <iframe data-w-type="embedded" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://sgx7y.mjt.lu/wgt/sgx7y/xtn1/form?c=c9b8015e" width="100%" style="height: 0;"></iframe> + <iframe data-w-type="embedded" title="Newsletter" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://sgx7y.mjt.lu/wgt/sgx7y/xtn1/form?c=c9b8015e" width="100%" style="height: 0;"></iframe> <script type="text/javascript" src="https://app.mailjet.com/pas-nc-embedded-v1.js"></script> </div> \ No newline at end of file diff --git a/portfolio/templates/portfolio/portfolio_page.html b/portfolio/templates/portfolio/portfolio_page.html index 8e395fe..2e3a8a5 100644 --- a/portfolio/templates/portfolio/portfolio_page.html +++ b/portfolio/templates/portfolio/portfolio_page.html @@ -4,8 +4,14 @@ {% block body_class %}template-portfolio{% endblock %} -{% block content %} - <h1>{{ page.title }}</h1> - {{ page.body }} +{% block content %} + <section class="flex flex-col items-center justify-center h-full px-0 md:px-4 lg:px-8"> + <article class="mb-16 px-1 md:px-4 lg:px-8"> + <h1>{{ page.title }}</h1> + <div class="blog-content w-full"> + {{ page.body }} + </div> + </article> + </section> {% endblock %} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 69558ab..0f0ad01 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -Django>=4.2,<5.2 -wagtail>=6.3,<6.4 +Django>=5.2.1,<5.3 +wagtail>=6.4,<7.1 whitenoise>=6.6,<7.0 wagtailcodeblock>=1.29.0.2,<2.0 django-tailwind>=3.6.0 -django-browser-reload>=1.12 +django-browser-reload>=1.17 Wand==0.6.13 -wagtail-seo==2.5.0 \ No newline at end of file +wagtail-seo==3.0.0 \ No newline at end of file diff --git a/search/templates/search/search.html b/search/templates/search/search.html index 0a067f5..75556cb 100644 --- a/search/templates/search/search.html +++ b/search/templates/search/search.html @@ -13,13 +13,11 @@ <form action="{% url 'search' %}" method="get" class="container"> <div class="flex flex-col space-y-4"> <label for="query" class="sr-only block text-sm font-medium leading-6">Search</label> - <div class="mt-2"> + <div class="mt-2 flex space-x-4"> <input type="text" placeholder="Type search keywords..." - class="block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-klavender sm:text-sm sm:leading-6" + class="block w-full rounded-xl border-0 py-1.5 px-2 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-klavender sm:text-sm sm:leading-6" id="query" name="query"{% if search_query %} value="{{ search_query }}"{% endif %}> - </div> - <div> <input type="submit" class="primary-button" value="Search"> </div> </div> @@ -30,7 +28,7 @@ </div> </section> - <section class="h-full px-0 md:px-4 lg:px-8"> + <section class="h-full px-0 md:px-4 lg:px-8 search"> <div class="px-0 md:px-4 lg:px-8"> <h2 class="sr-only">Search results</h2> @@ -48,6 +46,8 @@ <h4><a href="{% pageurl result %}">{{ result }}</a></h4> {% if result.search_description %} {{ result.search_description }} + {% elif result.post.intro %} + {{ result.post.intro }} {% endif %} </li> {% endfor %} diff --git a/theme/static_src/src/styles.css b/theme/static_src/src/styles.css index 3a2011b..a93a4a8 100644 --- a/theme/static_src/src/styles.css +++ b/theme/static_src/src/styles.css @@ -45,7 +45,7 @@ } h3 { - @apply mt-12 mb-2 text-xl sm:text-2xl lg:text-2xl leading-none font-extrabold tracking-tight text-black dark:text-white; + @apply mt-10 mb-3 text-xl sm:text-2xl lg:text-2xl leading-none font-extrabold tracking-tight text-black dark:text-white; } h4 { @@ -56,11 +56,23 @@ @apply my-2 mb-3 text-lg leading-relaxed; } + li { + @apply my-2 text-lg; + } + + .search li { + @apply my-6; + } + + .search li h4 { + @apply inline; + } + .blog-content ul, .home-content ul { @apply list-none list-inside; } - .blog-content ul li::before, .home-content ul li::before { + .blog-content ul li::before, .home-content ul li::before, .search li::before { content: "👉"; font-family: NotoEmoji; @apply inline-block mr-2 py-1; @@ -77,24 +89,57 @@ @media print { h1 { - @apply mt-6 mb-4 text-xl; + @apply m-0 my-2 text-xl; } h2 { - @apply mt-4 mb-2 text-base; + @apply m-0 mt-2 text-base; } h3 { - @apply text-base; + @apply m-0 mt-2 text-base; + } + + h4 { + @apply m-0 text-base; } p { @apply text-sm my-1; } + li { + @apply text-sm my-0; + } + .ppb { page-break-before: always; } + + nav.main { + @apply hidden; + } + + main { + @apply mx-0 px-0; + } + + footer { + @apply hidden !important; + } + + nav.return { + @apply hidden; + } + + /*.blog-content ul, .home-content ul {*/ + /* @apply list-none list-inside list-disc;*/ + /* @apply inline-block mr-0;*/ + /*}*/ + + /*.blog-content ul li::before, .home-content ul li::before, .search li::before {*/ + /* content: "";*/ + /*}*/ } .primary-button { @@ -112,11 +157,11 @@ } .tags ul { - @apply flex space-x-4 text-center text-sm; + @apply flex-col sm:flex-row sm:space-x-2 text-center text-sm; } .tags li { - @apply p-4 inline-flex items-center rounded-2xl bg-green-50 px-2 py-1 font-medium text-green-700 ring-1 ring-inset ring-green-600/20; + @apply p-3 inline-flex items-center rounded-2xl px-2 py-1 text-sm text-black dark:text-white ring-1 ring-inset ring-orange-700/20 dark:ring-white bg-orange-50 dark:bg-transparent; } .tags ul li::before { @@ -125,7 +170,7 @@ } .tags a { - @apply border-b-0 w-full; + @apply border-b-0 w-full m-0; } .blog-pages a {