picata 0.0.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. LICENSE.md +24 -0
  2. README.md +59 -0
  3. components/HelloWorld.tsx +11 -0
  4. entrypoint.tsx +268 -0
  5. manage.py +15 -0
  6. picata/__init__.py +1 -0
  7. picata/apps.py +33 -0
  8. picata/blocks.py +175 -0
  9. picata/helpers/__init__.py +70 -0
  10. picata/helpers/wagtail.py +61 -0
  11. picata/log_utils.py +47 -0
  12. picata/middleware.py +54 -0
  13. picata/migrations/0001_initial.py +264 -0
  14. picata/migrations/0002_alter_article_content_alter_basicpage_content.py +112 -0
  15. picata/migrations/0003_alter_article_content_alter_basicpage_content.py +104 -0
  16. picata/migrations/0004_alter_article_content_alter_basicpage_content.py +105 -0
  17. picata/migrations/0005_socialsettings.py +48 -0
  18. picata/migrations/0006_alter_article_content.py +71 -0
  19. picata/migrations/0007_splitviewpage.py +69 -0
  20. picata/migrations/0008_alter_splitviewpage_content.py +96 -0
  21. picata/migrations/0009_alter_splitviewpage_content.py +111 -0
  22. picata/migrations/0010_alter_splitviewpage_content.py +105 -0
  23. picata/migrations/0011_alter_splitviewpage_options_and_more.py +113 -0
  24. picata/migrations/0012_alter_splitviewpage_content.py +109 -0
  25. picata/migrations/0013_alter_article_content.py +43 -0
  26. picata/migrations/0014_alter_article_content_alter_article_summary.py +24 -0
  27. picata/migrations/0015_alter_article_options_article_tagline_and_more.py +28 -0
  28. picata/migrations/0016_alter_article_options_alter_articletag_options_and_more.py +33 -0
  29. picata/migrations/0017_articletagrelation_alter_article_tags_and_more.py +35 -0
  30. picata/migrations/0018_rename_articletag_pagetag_and_more.py +21 -0
  31. picata/migrations/0019_rename_name_plural_articletype__name_plural.py +18 -0
  32. picata/migrations/0020_rename__name_plural_articletype__pluralised_name.py +18 -0
  33. picata/migrations/0021_rename_article_type_article_page_type.py +18 -0
  34. picata/migrations/0022_homepage.py +28 -0
  35. picata/migrations/__init__.py +0 -0
  36. picata/models.py +486 -0
  37. picata/settings/__init__.py +1 -0
  38. picata/settings/base.py +345 -0
  39. picata/settings/dev.py +94 -0
  40. picata/settings/mypy.py +7 -0
  41. picata/settings/prod.py +12 -0
  42. picata/settings/test.py +6 -0
  43. picata/static/picata/ada-profile.jpg +0 -0
  44. picata/static/picata/ada-social-bear.jpg +0 -0
  45. picata/static/picata/favicon.ico +0 -0
  46. picata/static/picata/fonts/Bitter-Light.ttf +0 -0
  47. picata/static/picata/fonts/Bitter-LightItalic.ttf +0 -0
  48. picata/static/picata/fonts/FiraCode-Light.ttf +0 -0
  49. picata/static/picata/fonts/FiraCode-SemiBold.ttf +0 -0
  50. picata/static/picata/fonts/Sacramento-Regular.ttf +0 -0
  51. picata/static/picata/fonts/ZillaSlab-Bold.ttf +0 -0
  52. picata/static/picata/fonts/ZillaSlab-BoldItalic.ttf +0 -0
  53. picata/static/picata/fonts/ZillaSlab-Light.ttf +0 -0
  54. picata/static/picata/fonts/ZillaSlab-LightItalic.ttf +0 -0
  55. picata/static/picata/fonts/ZillaSlabHighlight-Bold.ttf +0 -0
  56. picata/static/picata/icons.svg +56 -0
  57. picata/templates/picata/3_column.html +28 -0
  58. picata/templates/picata/404.html +11 -0
  59. picata/templates/picata/500.html +13 -0
  60. picata/templates/picata/_post_list.html +24 -0
  61. picata/templates/picata/article.html +20 -0
  62. picata/templates/picata/base.html +135 -0
  63. picata/templates/picata/basic_page.html +10 -0
  64. picata/templates/picata/blocks/icon_link_item.html +7 -0
  65. picata/templates/picata/blocks/icon_link_list.html +4 -0
  66. picata/templates/picata/blocks/icon_link_list_stream.html +3 -0
  67. picata/templates/picata/dl_view.html +18 -0
  68. picata/templates/picata/home_page.html +21 -0
  69. picata/templates/picata/post_listing.html +17 -0
  70. picata/templates/picata/previews/3col.html +73 -0
  71. picata/templates/picata/previews/dl.html +10 -0
  72. picata/templates/picata/previews/split.html +10 -0
  73. picata/templates/picata/previews/theme_gallery.html +158 -0
  74. picata/templates/picata/search_results.html +28 -0
  75. picata/templates/picata/split_view.html +15 -0
  76. picata/templates/picata/tags/site_menu.html +8 -0
  77. picata/templatetags/__init__.py +1 -0
  78. picata/templatetags/absolute_static.py +15 -0
  79. picata/templatetags/menu_tags.py +42 -0
  80. picata/templatetags/stringify.py +23 -0
  81. picata/transformers.py +60 -0
  82. picata/typing/__init__.py +19 -0
  83. picata/typing/wagtail.py +31 -0
  84. picata/urls.py +48 -0
  85. picata/validators.py +36 -0
  86. picata/views.py +80 -0
  87. picata/wagtail_hooks.py +43 -0
  88. picata/wsgi.py +15 -0
  89. picata-0.0.1.dist-info/METADATA +87 -0
  90. picata-0.0.1.dist-info/RECORD +94 -0
  91. picata-0.0.1.dist-info/WHEEL +4 -0
  92. picata-0.0.1.dist-info/licenses/LICENSE.md +24 -0
  93. pygments.sass +382 -0
  94. styles.sass +300 -0
@@ -0,0 +1,345 @@
1
+ """Django settings for the project.
2
+
3
+ Generated by 'django-admin startproject' using Django 5.1.
4
+
5
+ For more information on this file, see
6
+ https://docs.djangoproject.com/en/5.1/topics/settings/
7
+
8
+ For the full list of settings and their values, see
9
+ https://docs.djangoproject.com/en/5.1/ref/settings/
10
+ """
11
+
12
+ import contextlib
13
+ from os import getenv
14
+ from pathlib import Path
15
+
16
+ from hpk.helpers import get_public_ip
17
+ from hpk.log_utils import FormatterWithEverything
18
+
19
+ SRC_DIR = Path(__file__).resolve().parent.parent.parent
20
+ BASE_DIR = Path(SRC_DIR).parent
21
+ LOG_DIR = BASE_DIR / "logs"
22
+
23
+ INTERNAL_IPS = ["*"]
24
+
25
+ ALLOWED_HOSTS = [*getenv("FQDN", "").split(), "localhost", "127.0.0.1"]
26
+ with contextlib.suppress(Exception):
27
+ public_ip = get_public_ip()
28
+ if public_ip:
29
+ ALLOWED_HOSTS.append(str(public_ip))
30
+
31
+ SECRET_KEY = getenv("SECRET_KEY")
32
+
33
+
34
+ # Application definition
35
+
36
+ INSTALLED_APPS = [
37
+ # Local apps
38
+ "hpk.apps.Config",
39
+ # Wagtail
40
+ "wagtail.contrib.forms",
41
+ "wagtail.contrib.redirects",
42
+ "wagtail.contrib.routable_page",
43
+ "wagtail.contrib.settings",
44
+ "wagtail.embeds",
45
+ "wagtail.sites",
46
+ "wagtail.users",
47
+ "wagtail.snippets",
48
+ "wagtail.documents",
49
+ "wagtail.images",
50
+ "wagtail.search",
51
+ "wagtail.admin",
52
+ "wagtail_modeladmin",
53
+ "wagtail",
54
+ "modelcluster",
55
+ "taggit",
56
+ # Django apps
57
+ "django.contrib.admin",
58
+ "django.contrib.auth",
59
+ "django.contrib.contenttypes",
60
+ "django.contrib.sessions",
61
+ "django.contrib.sitemaps",
62
+ "django.contrib.messages",
63
+ "django.contrib.staticfiles",
64
+ ]
65
+
66
+ MIDDLEWARE = [
67
+ "django.contrib.sessions.middleware.SessionMiddleware",
68
+ "django.middleware.common.CommonMiddleware",
69
+ "django.middleware.csrf.CsrfViewMiddleware",
70
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
71
+ "django.contrib.messages.middleware.MessageMiddleware",
72
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
73
+ "django.middleware.security.SecurityMiddleware",
74
+ "wagtail.contrib.redirects.middleware.RedirectMiddleware",
75
+ "hpk.middleware.HTMLProcessingMiddleware",
76
+ ]
77
+
78
+ ROOT_URLCONF = "hpk.urls"
79
+
80
+ TEMPLATES = [
81
+ {
82
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
83
+ "DIRS": [SRC_DIR / "templates"],
84
+ "APP_DIRS": True,
85
+ "OPTIONS": {
86
+ "context_processors": [
87
+ "django.template.context_processors.debug",
88
+ "django.template.context_processors.request",
89
+ "django.contrib.auth.context_processors.auth",
90
+ "django.contrib.messages.context_processors.messages",
91
+ "wagtail.contrib.settings.context_processors.settings",
92
+ ],
93
+ },
94
+ },
95
+ ]
96
+
97
+ WSGI_APPLICATION = "hpk.wsgi.application"
98
+
99
+
100
+ # Database
101
+ # https://docs.djangoproject.com/en/5.1/ref/settings/#databases
102
+
103
+ DATABASES = {
104
+ "default": {
105
+ "ENGINE": "django.db.backends.postgresql",
106
+ "NAME": getenv("DB_NAME"),
107
+ "USER": getenv("DB_USER"),
108
+ "PASSWORD": getenv("DB_PASSWORD"),
109
+ "HOST": getenv("DB_HOST", "localhost"),
110
+ "PORT": "5432",
111
+ },
112
+ }
113
+
114
+
115
+ # Password validation
116
+ # https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators
117
+
118
+ AUTH_PASSWORD_VALIDATORS = [
119
+ {
120
+ "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
121
+ },
122
+ {
123
+ "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
124
+ },
125
+ {
126
+ "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
127
+ },
128
+ {
129
+ "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
130
+ },
131
+ ]
132
+
133
+
134
+ # Logging
135
+ # https://docs.djangoproject.com/en/5.1/topics/logging/
136
+
137
+ LOGGING = {
138
+ "version": 1,
139
+ "disable_existing_loggers": False,
140
+ "formatters": {
141
+ "complete": {
142
+ "()": FormatterWithEverything,
143
+ },
144
+ "verbose": {
145
+ "format": "----\n{levelname} {asctime} {name}:{module}\n{message}",
146
+ "style": "{",
147
+ },
148
+ "simple": {
149
+ "format": "{levelname} {module}: {message}",
150
+ "style": "{",
151
+ },
152
+ },
153
+ "handlers": {
154
+ "console": {
155
+ "class": "logging.StreamHandler",
156
+ "formatter": "verbose",
157
+ "level": "INFO",
158
+ },
159
+ "django_log": {
160
+ "level": "INFO",
161
+ "class": "hpk.log_utils.RotatingDailyFileHandler",
162
+ "filename": LOG_DIR / "django.log",
163
+ "formatter": "verbose",
164
+ },
165
+ "hpk_log": {
166
+ "level": "INFO",
167
+ "class": "hpk.log_utils.RotatingDailyFileHandler",
168
+ "filename": LOG_DIR / "hpk.log",
169
+ "formatter": "verbose",
170
+ },
171
+ "warnings_log": {
172
+ "level": "WARNING",
173
+ "class": "logging.handlers.RotatingFileHandler",
174
+ "filename": LOG_DIR / "warnings.log",
175
+ "maxBytes": 1024 * 1024 * 5,
176
+ "backupCount": 5,
177
+ "formatter": "verbose",
178
+ },
179
+ },
180
+ "loggers": {
181
+ "hpk": {
182
+ "handlers": ["hpk_log"],
183
+ "level": "INFO",
184
+ "propagate": True,
185
+ },
186
+ "django": {
187
+ "handlers": ["django_log", "warnings_log"],
188
+ "level": "INFO",
189
+ "propagate": True,
190
+ },
191
+ "django.request": {
192
+ "handlers": ["django_log", "warnings_log"],
193
+ "level": "WARNING",
194
+ "propagate": False,
195
+ },
196
+ "django.template": {
197
+ "handlers": ["django_log", "warnings_log"],
198
+ "level": "WARNING",
199
+ "propagate": False,
200
+ },
201
+ "wagtail": {
202
+ "handlers": ["django_log", "warnings_log"],
203
+ "level": "WARNING",
204
+ "propagate": True,
205
+ },
206
+ "gunicorn.error": {
207
+ "handlers": ["console"],
208
+ "level": "ERROR",
209
+ "propagate": False,
210
+ },
211
+ "watchdog.observers.inotify_buffer": {
212
+ "handlers": ["console"],
213
+ "level": "WARNING",
214
+ "propagate": False,
215
+ },
216
+ },
217
+ "root": {
218
+ "handlers": ["console"],
219
+ "level": "INFO",
220
+ },
221
+ }
222
+
223
+
224
+ # Internationalization
225
+ # See https://docs.djangoproject.com/en/5.1/topics/i18n/
226
+
227
+ LANGUAGE_CODE = "en-us"
228
+
229
+ TIME_ZONE = getenv("TIMEZONE", "UTC")
230
+
231
+ USE_I18N = True
232
+
233
+ USE_TZ = True
234
+
235
+
236
+ # Static files (CSS, JavaScript, Images)
237
+ # https://docs.djangoproject.com/en/5.1/howto/static-files/
238
+
239
+ STATICFILES_FINDERS = [
240
+ "django.contrib.staticfiles.finders.FileSystemFinder",
241
+ "django.contrib.staticfiles.finders.AppDirectoriesFinder",
242
+ ]
243
+
244
+ STATICFILES_DIRS = [
245
+ SRC_DIR / "static",
246
+ BASE_DIR / "build/webpack",
247
+ ]
248
+
249
+ STATIC_ROOT = BASE_DIR / "static"
250
+ STATIC_URL = "/static/"
251
+
252
+ MEDIA_ROOT = BASE_DIR / "media"
253
+ MEDIA_URL = "/media/"
254
+
255
+ # Default storage settings, with the staticfiles storage updated.
256
+ # See https://docs.djangoproject.com/en/5.1/ref/settings/#std-setting-STORAGES
257
+ STORAGES = {
258
+ "default": {
259
+ "BACKEND": "django.core.files.storage.FileSystemStorage",
260
+ },
261
+ "staticfiles": {
262
+ "BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
263
+ },
264
+ }
265
+
266
+
267
+ # Email
268
+ # See https://docs.djangoproject.com/en/5.1/topics/email/
269
+
270
+ EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
271
+ EMAIL_HOST = "smtp.gmail.com"
272
+ EMAIL_PORT = 587
273
+ EMAIL_USE_TLS = True
274
+ EMAIL_HOST_USER = getenv("ADMIN_EMAIL")
275
+ EMAIL_HOST_PASSWORD = getenv("GMAIL_PASSWORD")
276
+ DEFAULT_FROM_EMAIL = getenv("ADMIN_EMAIL")
277
+
278
+
279
+ # Wagtail
280
+ # See https://docs.wagtail.org/en/stable/
281
+
282
+ WAGTAIL_SITE_NAME = "Hpk.io"
283
+
284
+ # Image serving
285
+ WAGTAILIMAGES_IMAGE_MODEL = "wagtailimages.Image"
286
+ WAGTAILIMAGES_SERVE_METHOD = "wagtail.images.views.serve.ServeView.as_view"
287
+
288
+ # Search - https://docs.wagtail.org/en/stable/topics/search/backends.html
289
+ WAGTAILSEARCH_BACKENDS = {
290
+ "default": {
291
+ "BACKEND": "wagtail.search.backends.database",
292
+ },
293
+ }
294
+
295
+ # Base URL to use when referring to full URLs within the Wagtail admin backend -
296
+ # e.g. in notification emails. Don't include '/admin' or a trailing slash
297
+ WAGTAILADMIN_BASE_URL = "https://" + getenv("FQDN", "hpk.io")
298
+
299
+ # https://docs.wagtail.org/en/stable/reference/settings.html#general-editing
300
+ WAGTAILADMIN_RICH_TEXT_EDITORS = {
301
+ "default": {
302
+ "WIDGET": "wagtail.admin.rich_text.DraftailRichTextArea",
303
+ "OPTIONS": {
304
+ "features": [
305
+ "h1",
306
+ "h2",
307
+ "h3",
308
+ "h4",
309
+ "h5",
310
+ "h6",
311
+ "bold",
312
+ "italic",
313
+ "ol",
314
+ "ul",
315
+ "code",
316
+ "blockquote",
317
+ "hr",
318
+ "link",
319
+ "document-link",
320
+ "image",
321
+ "embed",
322
+ "superscript",
323
+ "subscript",
324
+ "strikethrough",
325
+ ]
326
+ },
327
+ },
328
+ }
329
+
330
+ # Allowed file extensions for documents in the document library.
331
+ # This can be omitted to allow all files, but note that this may present a security risk
332
+ # if untrusted users are allowed to upload files -
333
+ # see https://docs.wagtail.org/en/stable/advanced_topics/deploying.html#user-uploaded-files
334
+ WAGTAILDOCS_EXTENSIONS = [
335
+ "csv",
336
+ "docx",
337
+ "key",
338
+ "odt",
339
+ "pdf",
340
+ "pptx",
341
+ "rtf",
342
+ "txt",
343
+ "xlsx",
344
+ "zip",
345
+ ]
picata/settings/dev.py ADDED
@@ -0,0 +1,94 @@
1
+ # ruff: noqa: F405 ERA001
2
+ # mypy: disable-error-code="index"
3
+ # pyright: reportCallIssue=false, reportArgumentType=false
4
+ """Django settings for development environments."""
5
+
6
+ import logging
7
+
8
+ from .base import * # noqa: F403
9
+ from .base import LOGGING
10
+
11
+ # NB: The logging system isn't set up yet; this is the "root" logger, which'll just write to stderr
12
+ logger = logging.getLogger()
13
+
14
+ DEBUG = True
15
+ USE_X_FORWARDED_HOST = True
16
+
17
+ # Security
18
+ SECRET_KEY = "django-insecure-9yz$rw8%)1wm-l)j6q-r&$bu_n52sv=4q6)c5u8n10+5w+anec" # noqa: S105
19
+
20
+ CLASS_C_NETWORK_ADDR = ["192.168.1.188"]
21
+ CLASS_C_DEVICE_ADDRS = [*CLASS_C_NETWORK_ADDR, "192.168.1.152", "192.168.1.240"]
22
+
23
+ INTERNAL_IPS = [*getenv("INTERNAL_IPS", "").split(), "localhost", "127.0.0.1"]
24
+ with contextlib.suppress(Exception):
25
+ public_ip = get_public_ip()
26
+ if public_ip:
27
+ INTERNAL_IPS.append(str(public_ip))
28
+
29
+ INTERNAL_IPS += CLASS_C_DEVICE_ADDRS
30
+ ALLOWED_HOSTS += CLASS_C_NETWORK_ADDR
31
+
32
+ if getenv("DJANGO_MANAGEMENT_COMMAND", "").startswith("runserver"):
33
+ logger.warning(
34
+ f"Loading hpk.settings.dev…\nINTERNAL_IPS = {INTERNAL_IPS}\nALLOWED_HOSTS = {ALLOWED_HOSTS}"
35
+ )
36
+
37
+ RUNSERVERPLUS_POLLER_RELOADER_TYPE = "watchdog"
38
+ RUNSERVER_PLUS_EXCLUDE_PATTERNS = [
39
+ ".venv/*",
40
+ ".vscode/*",
41
+ "build/*",
42
+ "infra/*",
43
+ "node_modules/*",
44
+ "lib/*",
45
+ "logs/*",
46
+ "media/*",
47
+ "snapshots/*",
48
+ "src/migrations/*",
49
+ "src/static/*",
50
+ "static/*",
51
+ ]
52
+
53
+ # Enable Django Debug Toolbar and runserver_plus
54
+ INSTALLED_APPS += [
55
+ "debug_toolbar",
56
+ "django_extensions",
57
+ ]
58
+ MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware", *MIDDLEWARE]
59
+
60
+
61
+ # Create staticfiles.json manifest and hashed files when collecting static files
62
+ if getenv("DJANGO_MANAGEMENT_COMMAND") == "collectstatic":
63
+ STORAGES["staticfiles"]["BACKEND"] = (
64
+ "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
65
+ )
66
+
67
+
68
+ # Enable extra information in template contexts for debugging
69
+ TEMPLATES[0]["OPTIONS"]["debug"] = True
70
+
71
+
72
+ # Logging (tuned for debugging)
73
+ LOGGING["handlers"]["console"]["level"] = "DEBUG"
74
+
75
+ LOGGING["root"]["level"] = "DEBUG"
76
+
77
+ LOGGING["loggers"]["gunicorn"] = {
78
+ "handlers": ["console"],
79
+ "level": "INFO",
80
+ "propagate": False,
81
+ }
82
+
83
+ LOGGING["loggers"]["hpk"]["level"] = "DEBUG"
84
+
85
+ LOGGING["loggers"]["django"]["level"] = "DEBUG"
86
+ LOGGING["loggers"]["django.db.backends"] = {"level": "INFO"}
87
+ LOGGING["loggers"]["django.template"]["level"] = "INFO"
88
+ LOGGING["loggers"]["django.request"]["level"] = "DEBUG"
89
+ LOGGING["loggers"]["django.request"]["handlers"] += ["console"]
90
+ LOGGING["loggers"]["django.utils"] = {"level": "INFO"}
91
+
92
+ LOGGING["loggers"]["wagtail"]["level"] = "DEBUG"
93
+
94
+ LOGGING["loggers"]["asyncio"] = {"level": "INFO"}
@@ -0,0 +1,7 @@
1
+ """Django settings for the mypy type-checking daemon."""
2
+
3
+ import django_stubs_ext
4
+
5
+ from .dev import * # noqa: F403
6
+
7
+ django_stubs_ext.monkeypatch()
@@ -0,0 +1,12 @@
1
+ """Django settings for production environments."""
2
+ # ruff: noqa: F405
3
+
4
+ from .base import * # noqa: F403
5
+
6
+ # ManifestStaticFilesStorage is recommended in production, to prevent
7
+ # outdated JavaScript / CSS assets being served from cache
8
+ # (e.g. after a Wagtail upgrade).
9
+ # See https://docs.djangoproject.com/en/5.1/ref/contrib/staticfiles/#manifeststaticfilesstorage
10
+ STORAGES["staticfiles"] = {
11
+ "BACKEND": "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
12
+ }
@@ -0,0 +1,6 @@
1
+ """Django settings for test environments."""
2
+
3
+ from .base import * # noqa: F403
4
+
5
+ # SECURITY WARNING: keep the secret key used in production secret!
6
+ SECRET_KEY = "django-insecure-9yz$rw8%)1wm-l)j6q-r&$bu_n52sv=4q6)c5u8n10+5w+anec" # noqa: S105
Binary file
Binary file
Binary file
@@ -0,0 +1,56 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
2
+ <symbol id="mastodon" viewBox="0 0 16 16">
3
+ <path d="M11.19 12.195c2.016-.24 3.77-1.475 3.99-2.603.348-1.778.32-4.339.32-4.339 0-3.47-2.286-4.488-2.286-4.488C12.062.238 10.083.017 8.027 0h-.05C5.92.017 3.942.238 2.79.765c0 0-2.285 1.017-2.285 4.488l-.002.662c-.004.64-.007 1.35.011 2.091.083 3.394.626 6.74 3.78 7.57 1.454.383 2.703.463 3.709.408 1.823-.1 2.847-.647 2.847-.647l-.06-1.317s-1.303.41-2.767.36c-1.45-.05-2.98-.156-3.215-1.928a4 4 0 0 1-.033-.496s1.424.346 3.228.428c1.103.05 2.137-.064 3.188-.189zm1.613-2.47H11.13v-4.08c0-.859-.364-1.295-1.091-1.295-.804 0-1.207.517-1.207 1.541v2.233H7.168V5.89c0-1.024-.403-1.541-1.207-1.541-.727 0-1.091.436-1.091 1.296v4.079H3.197V5.522q0-1.288.66-2.046c.456-.505 1.052-.764 1.793-.764.856 0 1.504.328 1.933.983L8 4.39l.417-.695c.429-.655 1.077-.983 1.934-.983.74 0 1.336.259 1.791.764q.662.757.661 2.046z"/>
4
+ </symbol>
5
+ <symbol id="github" viewBox="0 0 16 16">
6
+ <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
7
+ </symbol>
8
+ <symbol id="substack" viewBox="0 0 16 16">
9
+ <path d="M15 3.604H1v1.891h14v-1.89ZM1 7.208V16l7-3.926L15 16V7.208zM15 0H1v1.89h14z"/>
10
+ </symbol>
11
+ <symbol id="stackoverflow" viewBox="0 0 16 16">
12
+ <path d="M12.412 14.572V10.29h1.428V16H1v-5.71h1.428v4.282z"/>
13
+ <path d="M3.857 13.145h7.137v-1.428H3.857zM10.254 0 9.108.852l4.26 5.727 1.146-.852zm-3.54 3.377 5.484 4.567.913-1.097L7.627 2.28l-.914 1.097zM4.922 6.55l6.47 3.013.603-1.294-6.47-3.013zm-.925 3.344 6.985 1.469.294-1.398-6.985-1.468z"/>
14
+ </symbol>
15
+ <symbol id="linkedin" viewBox="0 0 16 16">
16
+ <path d="M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854zm4.943 12.248V6.169H2.542v7.225zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248S2.4 3.226 2.4 3.934c0 .694.521 1.248 1.327 1.248zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016l.016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225z"/>
17
+ </symbol>
18
+ <symbol id="facebook" viewBox="0 0 16 16">
19
+ <path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951"/>
20
+ </symbol>
21
+ <symbol id="instagram" viewBox="0 0 16 16">
22
+ <path d="M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.9 3.9 0 0 0-1.417.923A3.9 3.9 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.9 3.9 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.9 3.9 0 0 0-.923-1.417A3.9 3.9 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599s.453.546.598.92c.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.5 2.5 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.5 2.5 0 0 1-.92-.598 2.5 2.5 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233s.008-2.388.046-3.231c.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92s.546-.453.92-.598c.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92m-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217m0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334"/>
23
+ </symbol>
24
+ <symbol id="medium" viewBox="0 0 16 16">
25
+ <path d="M9.025 8c0 2.485-2.02 4.5-4.513 4.5A4.506 4.506 0 0 1 0 8c0-2.486 2.02-4.5 4.512-4.5A4.506 4.506 0 0 1 9.025 8m4.95 0c0 2.34-1.01 4.236-2.256 4.236S9.463 10.339 9.463 8c0-2.34 1.01-4.236 2.256-4.236S13.975 5.661 13.975 8M16 8c0 2.096-.355 3.795-.794 3.795-.438 0-.793-1.7-.793-3.795 0-2.096.355-3.795.794-3.795.438 0 .793 1.699.793 3.795"/>
26
+ </symbol>
27
+ <symbol id="messenger" viewBox="0 0 16 16">
28
+ <path d="M0 7.76C0 3.301 3.493 0 8 0s8 3.301 8 7.76-3.493 7.76-8 7.76c-.81 0-1.586-.107-2.316-.307a.64.64 0 0 0-.427.03l-1.588.702a.64.64 0 0 1-.898-.566l-.044-1.423a.64.64 0 0 0-.215-.456C.956 12.108 0 10.092 0 7.76m5.546-1.459-2.35 3.728c-.225.358.214.761.551.506l2.525-1.916a.48.48 0 0 1 .578-.002l1.869 1.402a1.2 1.2 0 0 0 1.735-.32l2.35-3.728c.226-.358-.214-.761-.551-.506L9.728 7.381a.48.48 0 0 1-.578.002L7.281 5.98a1.2 1.2 0 0 0-1.735.32z"/>
29
+ </symbol>
30
+ <symbol id="telegram" viewBox="0 0 16 16">
31
+ <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.287 5.906q-1.168.486-4.666 2.01-.567.225-.595.442c-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294q.39.01.868-.32 3.269-2.206 3.374-2.23c.05-.012.12-.026.166.016s.042.12.037.141c-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8 8 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629q.14.092.27.187c.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.4 1.4 0 0 0-.013-.315.34.34 0 0 0-.114-.217.53.53 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09"/>
32
+ </symbol>
33
+ <symbol id="threads" viewBox="0 0 16 16">
34
+ <path d="M6.321 6.016c-.27-.18-1.166-.802-1.166-.802.756-1.081 1.753-1.502 3.132-1.502.975 0 1.803.327 2.394.948s.928 1.509 1.005 2.644q.492.207.905.484c1.109.745 1.719 1.86 1.719 3.137 0 2.716-2.226 5.075-6.256 5.075C4.594 16 1 13.987 1 7.994 1 2.034 4.482 0 8.044 0 9.69 0 13.55.243 15 5.036l-1.36.353C12.516 1.974 10.163 1.43 8.006 1.43c-3.565 0-5.582 2.171-5.582 6.79 0 4.143 2.254 6.343 5.63 6.343 2.777 0 4.847-1.443 4.847-3.556 0-1.438-1.208-2.127-1.27-2.127-.236 1.234-.868 3.31-3.644 3.31-1.618 0-3.013-1.118-3.013-2.582 0-2.09 1.984-2.847 3.55-2.847.586 0 1.294.04 1.663.114 0-.637-.54-1.728-1.9-1.728-1.25 0-1.566.405-1.967.868ZM8.716 8.19c-2.04 0-2.304.87-2.304 1.416 0 .878 1.043 1.168 1.6 1.168 1.02 0 2.067-.282 2.232-2.423a6.2 6.2 0 0 0-1.528-.161"/>
35
+ </symbol>
36
+ <symbol id="twitch" viewBox="0 0 16 16">
37
+ <path d="M3.857 0 1 2.857v10.286h3.429V16l2.857-2.857H9.57L14.714 8V0zm9.714 7.429-2.285 2.285H9l-2 2v-2H4.429V1.143h9.142z"/>
38
+ <path d="M11.857 3.143h-1.143V6.57h1.143zm-3.143 0H7.571V6.57h1.143z"/>
39
+ </symbol>
40
+ <symbol id="whatsapp" viewBox="0 0 16 16">
41
+ <path d="M13.601 2.326A7.85 7.85 0 0 0 7.994 0C3.627 0 .068 3.558.064 7.926c0 1.399.366 2.76 1.057 3.965L0 16l4.204-1.102a7.9 7.9 0 0 0 3.79.965h.004c4.368 0 7.926-3.558 7.93-7.93A7.9 7.9 0 0 0 13.6 2.326zM7.994 14.521a6.6 6.6 0 0 1-3.356-.92l-.24-.144-2.494.654.666-2.433-.156-.251a6.56 6.56 0 0 1-1.007-3.505c0-3.626 2.957-6.584 6.591-6.584a6.56 6.56 0 0 1 4.66 1.931 6.56 6.56 0 0 1 1.928 4.66c-.004 3.639-2.961 6.592-6.592 6.592m3.615-4.934c-.197-.099-1.17-.578-1.353-.646-.182-.065-.315-.099-.445.099-.133.197-.513.646-.627.775-.114.133-.232.148-.43.05-.197-.1-.836-.308-1.592-.985-.59-.525-.985-1.175-1.103-1.372-.114-.198-.011-.304.088-.403.087-.088.197-.232.296-.346.1-.114.133-.198.198-.33.065-.134.034-.248-.015-.347-.05-.099-.445-1.076-.612-1.47-.16-.389-.323-.335-.445-.34-.114-.007-.247-.007-.38-.007a.73.73 0 0 0-.529.247c-.182.198-.691.677-.691 1.654s.71 1.916.81 2.049c.098.133 1.394 2.132 3.383 2.992.47.205.84.326 1.129.418.475.152.904.129 1.246.08.38-.058 1.171-.48 1.338-.943.164-.464.164-.86.114-.943-.049-.084-.182-.133-.38-.232"/>
42
+ </symbol>
43
+ <symbol id="youtube" viewBox="0 0 16 16">
44
+ <path d="M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 0 1 1.415 1.42c.101.38.172.883.22 1.402l.01.104.022.26.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105-.009.104c-.05.572-.124 1.14-.235 1.558a2.01 2.01 0 0 1-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006-.087-.004-.171-.007-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.01 2.01 0 0 1-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31 31 0 0 1 0 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103.003-.052.008-.104.022-.26.01-.104c.048-.519.119-1.023.22-1.402a2.01 2.01 0 0 1 1.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007.172-.006.086-.003.171-.007A100 100 0 0 1 7.858 2zM6.4 5.209v4.818l4.157-2.408z"/>
45
+ </symbol>
46
+ <symbol id="email" viewBox="0 0 16 16">
47
+ <path d="M2 2A2 2 0 0 0 .05 3.555L8 8.414l7.95-4.859A2 2 0 0 0 14 2zm-2 9.8V4.698l5.803 3.546zm6.761-2.97-6.57 4.026A2 2 0 0 0 2 14h6.256A4.5 4.5 0 0 1 8 12.5a4.49 4.49 0 0 1 1.606-3.446l-.367-.225L8 9.586zM16 9.671V4.697l-5.803 3.546.338.208A4.5 4.5 0 0 1 12.5 8c1.414 0 2.675.652 3.5 1.671"/>
48
+ <path d="M15.834 12.244c0 1.168-.577 2.025-1.587 2.025-.503 0-1.002-.228-1.12-.648h-.043c-.118.416-.543.643-1.015.643-.77 0-1.259-.542-1.259-1.434v-.529c0-.844.481-1.4 1.26-1.4.585 0 .87.333.953.63h.03v-.568h.905v2.19c0 .272.18.42.411.42.315 0 .639-.415.639-1.39v-.118c0-1.277-.95-2.326-2.484-2.326h-.04c-1.582 0-2.64 1.067-2.64 2.724v.157c0 1.867 1.237 2.654 2.57 2.654h.045c.507 0 .935-.07 1.18-.18v.731c-.219.1-.643.175-1.237.175h-.044C10.438 16 9 14.82 9 12.646v-.214C9 10.36 10.421 9 12.485 9h.035c2.12 0 3.314 1.43 3.314 3.034zm-4.04.21v.227c0 .586.227.8.581.8.31 0 .564-.17.564-.743v-.367c0-.516-.275-.708-.572-.708-.346 0-.573.245-.573.791"/>
49
+ </symbol>
50
+ <symbol id="twitter" viewBox="0 0 16 16">
51
+ <path d="M5.026 15c6.038 0 9.341-5.003 9.341-9.334q.002-.211-.006-.422A6.7 6.7 0 0 0 16 3.542a6.7 6.7 0 0 1-1.889.518 3.3 3.3 0 0 0 1.447-1.817 6.5 6.5 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.32 9.32 0 0 1-6.767-3.429 3.29 3.29 0 0 0 1.018 4.382A3.3 3.3 0 0 1 .64 6.575v.045a3.29 3.29 0 0 0 2.632 3.218 3.2 3.2 0 0 1-.865.115 3 3 0 0 1-.614-.057 3.28 3.28 0 0 0 3.067 2.277A6.6 6.6 0 0 1 .78 13.58a6 6 0 0 1-.78-.045A9.34 9.34 0 0 0 5.026 15"/>
52
+ </symbol>
53
+ <symbol id="bluesky" viewBox="0 0 24 24">
54
+ <path d="M18.231,3.618c-2.312,1.736-4.785,5.107-5.948,7.244c-0.123,0.226-0.444,0.226-0.567,0 c-1.163-2.137-3.636-5.508-5.948-7.244C3.949,2.252,1,1.195,1,4.559c0,0.672,0.385,5.643,0.611,6.451 c0.606,2.169,2.454,3.089,4.437,3.195c0.19,0.01,0.222,0.261,0.043,0.324c-2.988,1.048-3.518,3.196-1.424,5.344 c3.826,3.894,5.814,0.647,6.733-1.514c0.224-0.525,0.977-0.525,1.2,0c0.92,2.161,2.907,5.408,6.733,1.514 c2.093-2.148,1.564-4.296-1.424-5.344c-0.179-0.063-0.146-0.313,0.043-0.324c1.983-0.106,3.83-1.026,4.437-3.195 C22.615,10.203,23,5.231,23,4.559C23,1.195,20.051,2.252,18.231,3.618z"/>
55
+ </symbol>
56
+ </svg>
@@ -0,0 +1,28 @@
1
+ {% extends "base.html" %}
2
+ {% comment %}
3
+ Three-column layout, at `lg`-up, with a 25% aside, 50% article, and 25% nav.
4
+
5
+ Two columns at `sm` & `md`, 25% left with aside over nav; 50% for the article.
6
+
7
+ One column at `xs` down, with nav, the the article, followed by the aside.
8
+
9
+ Either override the "content" and provide all three elements, or override an
10
+ "aside", a "nav", and an "article" block, or provide "aside", "nav" and
11
+ "article" to the template context.
12
+ {% endcomment %}
13
+
14
+ {% load wagtailcore_tags %}
15
+
16
+ {% block main_classes %}three-column{% endblock %}
17
+
18
+ {% block content %}
19
+ <aside>{% block aside %}
20
+ {{ aside }}
21
+ {% endblock %}</aside>
22
+ <nav>{% block nav %}
23
+ {{ nav }}
24
+ {% endblock %}</nav>
25
+ <article>{% block article %}
26
+ {{ article }}
27
+ {% endblock %}</article>
28
+ {% endblock %}
@@ -0,0 +1,11 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Page not found{% endblock %}
4
+
5
+ {% block body_class %}template-404{% endblock %}
6
+
7
+ {% block content %}
8
+ <h1>Page not found</h1>
9
+
10
+ <h2>Sorry, this page could not be found.</h2>
11
+ {% endblock %}
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" dir="ltr">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Internal server error</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ </head>
8
+ <body>
9
+ <h1>Internal server error</h1>
10
+
11
+ <h2>Sorry, there seems to be an error. Please try again soon.</h2>
12
+ </body>
13
+ </html>
@@ -0,0 +1,24 @@
1
+ {% load wagtailcore_tags %}
2
+
3
+ {% for post in posts %}
4
+ <dt class="meta-data">
5
+ {% if year and forloop.counter == 1 %}<h2>{{ year }}</h2>{% endif %}
6
+ {% if post.published %}
7
+ Published <span>{{ post.published }}</span>
8
+ {% if post.updated %}
9
+ <br />Updated <span>{{ post.updated }}</span><br />
10
+ {% endif %}
11
+ {% endif %}
12
+ {% if post.latest_draft %}
13
+ <span><a href="{{ post.draft_url }}">Last draft</a></span>
14
+ <span>{{ post.latest_draft }}</span>
15
+ {% endif %}
16
+ {% if post.page_type %}<div class="page-type">{{ post.page_type.indefinite_article|capfirst }}
17
+ {% if post.tags %}, tagged:{% endif %}
18
+ </div>{% endif %}
19
+ </dt>
20
+ <dd class="preview">
21
+ <h3>{% if post.published %}<a href="{{ post.url }}">{% endif %}{{ post.title }}{% if post.published %}</a>{% endif %}</h3>
22
+ {% if post.summary %}{{ post.summary|richtext }}{% endif %}
23
+ </dd>
24
+ {% endfor %}