picata 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 %}