Compare commits
18 commits
Author | SHA1 | Date | |
---|---|---|---|
36e46f8cfd | |||
38d59de6c0 | |||
c42bfbe72d | |||
96633340cd | |||
c4a83cf5be | |||
9d5f6bc5fb | |||
00c7db9bec | |||
2a2c59d2b8 | |||
39f2433824 | |||
edb7a185d8 | |||
762d800ce4 | |||
e7cab9534e | |||
41508948c6 | |||
f8f7021198 | |||
21121e77ad | |||
3659cf902a | |||
e9e5e7d30b | |||
666fe03f2d |
15 changed files with 387 additions and 39 deletions
2
.idea/iamkonstantin-web.iml
generated
2
.idea/iamkonstantin-web.iml
generated
|
@ -17,7 +17,7 @@
|
||||||
<excludeFolder url="file://$MODULE_DIR$/env" />
|
<excludeFolder url="file://$MODULE_DIR$/env" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.13 (iamkonstantin-web)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.12 virtualenv at ~/Developer/personal/iamkonstantin-web/venv" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PyDocumentationSettings">
|
<component name="PyDocumentationSettings">
|
||||||
|
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
@ -3,5 +3,5 @@
|
||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="Python 3.12 (iamkonstantin-web)" />
|
<option name="sdkName" value="Python 3.12 (iamkonstantin-web)" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (iamkonstantin-web)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 virtualenv at ~/Developer/personal/iamkonstantin-web/venv" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
1
.tool-versions
Normal file
1
.tool-versions
Normal file
|
@ -0,0 +1 @@
|
||||||
|
python 3.12.8
|
7
Makefile
7
Makefile
|
@ -1,12 +1,9 @@
|
||||||
.PHONY: help build publish
|
.PHONY: help bump publish
|
||||||
VERSION = 1.7.0
|
VERSION = 1.9.15
|
||||||
|
|
||||||
help:
|
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}'
|
@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:
|
publish:
|
||||||
# something to try: --provenance=false
|
# something to try: --provenance=false
|
||||||
@docker buildx build -t code.headbright.be/konstantin/iamkonstantin:$(VERSION) --platform linux/arm64 --push .
|
@docker buildx build -t code.headbright.be/konstantin/iamkonstantin:$(VERSION) --platform linux/arm64 --push .
|
||||||
|
|
|
@ -5,6 +5,8 @@ from urllib.parse import urlparse
|
||||||
from base.indexnow import get_key
|
from base.indexnow import get_key
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from blog.models import BlogPage
|
||||||
|
|
||||||
|
|
||||||
@hooks.register('after_publish_page')
|
@hooks.register('after_publish_page')
|
||||||
def after_publish_page(request, page):
|
def after_publish_page(request, page):
|
||||||
|
@ -14,6 +16,9 @@ def after_publish_page(request, page):
|
||||||
if urlparse(page_url).hostname == "localhost":
|
if urlparse(page_url).hostname == "localhost":
|
||||||
print("not notifying indexnow for localhost" + get_key() + ", page url: " + page_url)
|
print("not notifying indexnow for localhost" + get_key() + ", page url: " + page_url)
|
||||||
return
|
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 = requests.Session()
|
||||||
session.post(
|
session.post(
|
||||||
"https://api.indexnow.org/indexnow",
|
"https://api.indexnow.org/indexnow",
|
||||||
|
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -5,7 +5,7 @@
|
||||||
{% block body_class %}template-blogpage{% endblock %}
|
{% block body_class %}template-blogpage{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="flex flex-col items-center justify-center h-full px-0 md:px-4 lg:px-8">
|
<section class="flex flex-col justify-center h-full px-0 md:px-4 lg:px-8">
|
||||||
<article class="mb-16 px-1 md:px-4 lg:px-8">
|
<article class="mb-16 px-1 md:px-4 lg:px-8">
|
||||||
<h1>{{ page.title }}</h1>
|
<h1>{{ page.title }}</h1>
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@
|
||||||
|
|
||||||
{% with tags=page.tags.all %}
|
{% with tags=page.tags.all %}
|
||||||
{% if tags %}
|
{% if tags %}
|
||||||
<div class="flex items-center gap-x-4 text-xs my-6">
|
<div class="flex items-center justify-center gap-x-4 text-xs my-6">
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<h2 class="sr-only">Tags</h2>
|
<h2 class="sr-only">Tags</h2>
|
||||||
<ul class="flex">
|
<ul class="flex">
|
||||||
{% for tag in tags %}
|
{% for tag in tags %}
|
||||||
<li class="space-x-2"><span class="emoji">🏷️</span>
|
<li><span class="emoji">🏷</span>
|
||||||
<a class="pr-2" href="{% slugurl 'tags' %}?tag={{ tag }}">{{ tag }}</a>
|
<a class="pr-2" href="{% slugurl 'tags' %}?tag={{ tag }}">{{ tag }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -74,13 +74,9 @@
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<nav class="w-full text-center px-2 lg:px-4">
|
<nav class="w-full text-center px-2 lg:px-4 return">
|
||||||
<a href="{{ page.get_parent.url }}" class="font-bold">Return to blog</a>
|
<a href="{{ page.get_parent.url }}" class="font-bold">Return to blog</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
|
||||||
{% include 'newsletter/snippets/signup_form.html' %}
|
|
||||||
</section>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -60,6 +60,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
<p class="mt-5 leading-6">{{ post.intro }}</p>
|
<p class="mt-5 leading-6">{{ post.intro }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if post.main_image %}
|
{% if post.main_image %}
|
||||||
<div class="relative mx-auto">
|
<div class="relative mx-auto">
|
||||||
{% with post.main_image as main_image %}
|
{% with post.main_image as main_image %}
|
||||||
|
@ -81,7 +82,4 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
|
||||||
{% include 'newsletter/snippets/signup_form.html' %}
|
|
||||||
</section>
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
|
@ -4,7 +4,8 @@
|
||||||
<html lang="en" class="h-full antialiased">
|
<html lang="en" class="h-full antialiased">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="fediverse:creator" content="@konstantin@toot.iamkonstantin.eu" />
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<meta name="fediverse:creator" content="@iamkonstantin@mastodon.social" />
|
||||||
{% include "wagtailseo/meta.html" %}
|
{% include "wagtailseo/meta.html" %}
|
||||||
<title>
|
<title>
|
||||||
{% block title %}
|
{% block title %}
|
||||||
|
@ -80,5 +81,6 @@
|
||||||
{# Override this in templates to add extra javascript #}
|
{# Override this in templates to add extra javascript #}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% include "wagtailseo/struct_data.html" %}
|
{% include "wagtailseo/struct_data.html" %}
|
||||||
|
{% include "wagtailseo/struct_org_data.html" %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<a href="#main" class="skip-link">Skip to content</a>
|
<a href="#main" class="skip-link">Skip to content</a>
|
||||||
|
|
||||||
{% get_site_root as site_root %}
|
{% 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">
|
<ul class="flex space-x-8">
|
||||||
<li><a href="{% pageurl site_root %}">{{ site_root.title }}</a></li>
|
<li><a href="{% pageurl site_root %}">{{ site_root.title }}</a></li>
|
||||||
{% for menuitem in site_root.get_children.live.in_menu %}
|
{% for menuitem in site_root.get_children.live.in_menu %}
|
||||||
|
|
|
@ -4,8 +4,14 @@
|
||||||
|
|
||||||
{% block body_class %}template-portfolio{% endblock %}
|
{% block body_class %}template-portfolio{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h1>{{ page.title }}</h1>
|
|
||||||
|
|
||||||
|
{% 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 }}
|
{{ page.body }}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,8 +1,8 @@
|
||||||
Django>=4.2,<5.2
|
Django>=5.2.1,<5.3
|
||||||
wagtail>=6.3.1,<6.4
|
wagtail>=6.4,<7.1
|
||||||
whitenoise>=6.6,<7.0
|
whitenoise>=6.6,<7.0
|
||||||
wagtailcodeblock>=1.29.0.2,<2.0
|
wagtailcodeblock>=1.29.0.2,<2.0
|
||||||
django-tailwind>=3.6.0
|
django-tailwind>=3.6.0
|
||||||
django-browser-reload>=1.17
|
django-browser-reload>=1.17
|
||||||
Wand==0.6.13
|
Wand==0.6.13
|
||||||
wagtail-seo==2.5.0
|
wagtail-seo==3.0.0
|
|
@ -13,13 +13,11 @@
|
||||||
<form action="{% url 'search' %}" method="get" class="container">
|
<form action="{% url 'search' %}" method="get" class="container">
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
<label for="query" class="sr-only block text-sm font-medium leading-6">Search</label>
|
<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..."
|
<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 %}>
|
id="query" name="query"{% if search_query %} value="{{ search_query }}"{% endif %}>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<input type="submit" class="primary-button" value="Search">
|
<input type="submit" class="primary-button" value="Search">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,7 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</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">
|
<div class="px-0 md:px-4 lg:px-8">
|
||||||
<h2 class="sr-only">Search results</h2>
|
<h2 class="sr-only">Search results</h2>
|
||||||
|
|
||||||
|
@ -48,6 +46,8 @@
|
||||||
<h4><a href="{% pageurl result %}">{{ result }}</a></h4>
|
<h4><a href="{% pageurl result %}">{{ result }}</a></h4>
|
||||||
{% if result.search_description %}
|
{% if result.search_description %}
|
||||||
{{ result.search_description }}
|
{{ result.search_description }}
|
||||||
|
{% elif result.post.intro %}
|
||||||
|
{{ result.post.intro }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
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 {
|
h4 {
|
||||||
|
@ -56,11 +56,23 @@
|
||||||
@apply my-2 mb-3 text-lg leading-relaxed;
|
@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 {
|
.blog-content ul, .home-content ul {
|
||||||
@apply list-none list-inside;
|
@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: "👉";
|
content: "👉";
|
||||||
font-family: NotoEmoji;
|
font-family: NotoEmoji;
|
||||||
@apply inline-block mr-2 py-1;
|
@apply inline-block mr-2 py-1;
|
||||||
|
@ -77,24 +89,57 @@
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
h1 {
|
h1 {
|
||||||
@apply mt-6 mb-4 text-xl;
|
@apply m-0 my-2 text-xl;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@apply mt-4 mb-2 text-base;
|
@apply m-0 mt-2 text-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
@apply text-base;
|
@apply m-0 mt-2 text-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
@apply m-0 text-base;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@apply text-sm my-1;
|
@apply text-sm my-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
@apply text-sm my-0;
|
||||||
|
}
|
||||||
|
|
||||||
.ppb {
|
.ppb {
|
||||||
page-break-before: always;
|
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 {
|
.primary-button {
|
||||||
|
@ -112,11 +157,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags ul {
|
.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 {
|
.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 {
|
.tags ul li::before {
|
||||||
|
@ -125,7 +170,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags a {
|
.tags a {
|
||||||
@apply border-b-0 w-full;
|
@apply border-b-0 w-full m-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blog-pages a {
|
.blog-pages a {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue