diff --git a/README.md b/README.md
index 2b3e4fa..71de1bb 100644
--- a/README.md
+++ b/README.md
@@ -4,5 +4,11 @@ Simple blog management system.
Hosted at https://gabnotes.org
-## Todo
-* Nothing 😴
+## Run locally
+Remember to run
+
+```bash
+./manage.py collectstatic --no-input && ./manage.py assets build --manifest django
+```
+
+Before running server and after editing static files.
diff --git a/ansible/blog.service b/ansible/blog.service
index c806e5c..3b14d15 100644
--- a/ansible/blog.service
+++ b/ansible/blog.service
@@ -28,6 +28,7 @@ blog_prestart()
. /srv/blog/.env
yes yes | /srv/blogvenv/bin/python /srv/blog/manage.py migrate
/srv/blogvenv/bin/python /srv/blog/manage.py collectstatic --noinput --clear
+ /srv/blogvenv/bin/python /srv/blog/manage.py assets build --manifest django
}
run_rc_command "$1"
diff --git a/articles/assets.py b/articles/assets.py
new file mode 100644
index 0000000..134b8f0
--- /dev/null
+++ b/articles/assets.py
@@ -0,0 +1,17 @@
+from django_assets import Bundle, register
+
+public_no_code = Bundle(
+ "newcss.css",
+ "public.css",
+ filters="cssmin",
+ output="public_bundled.css",
+)
+public_with_code = Bundle(
+ "newcss.css",
+ "codehilite.css",
+ "public.css",
+ filters="cssmin",
+ output="public_code_bundled.css",
+)
+register("public_no_code", public_no_code)
+register("public_with_code", public_with_code)
diff --git a/articles/templates/articles/base.html b/articles/templates/articles/base.html
index a4fc363..a90ecd5 100644
--- a/articles/templates/articles/base.html
+++ b/articles/templates/articles/base.html
@@ -1,4 +1,3 @@
-{% load static %}
@@ -6,18 +5,10 @@
- {% include "articles/snippets/page_metadata.html" %}
{% block title %}Home | {% endblock %}{{ blog_title }} by {{ blog_author }}
-
-
- {% if article and article.has_code %}
-
- {% endif %}
- {% if user.is_authenticated %}
-
-
- {% endif %}
+ {% include "articles/snippets/page_metadata.html" %}
+ {% include "articles/snippets/load_styles_and_scripts.html" %}
{% include "articles/snippets/favicon.html" %}
{% include "articles/snippets/analytics.html" %}
{% block append_header %}{% endblock %}
diff --git a/articles/templates/articles/snippets/load_styles_and_scripts.html b/articles/templates/articles/snippets/load_styles_and_scripts.html
new file mode 100644
index 0000000..5e4bf5e
--- /dev/null
+++ b/articles/templates/articles/snippets/load_styles_and_scripts.html
@@ -0,0 +1,16 @@
+{% load assets %}
+{% load static %}
+
+{% if article and article.has_code %}
+ {% assets "public_with_code" %}
+
+ {% endassets %}
+{% else %}
+ {% assets "public_no_code" %}
+
+ {% endassets %}
+{% endif %}
+{% if user.is_authenticated %}
+
+
+{% endif %}
diff --git a/blog/settings.py b/blog/settings.py
index a8e0e48..a3786f3 100644
--- a/blog/settings.py
+++ b/blog/settings.py
@@ -71,6 +71,7 @@ INSTALLED_APPS = [
"attachments",
"anymail",
"django_cleanup.apps.CleanupConfig",
+ "django_assets",
]
MIDDLEWARE = [
@@ -169,6 +170,12 @@ else:
"django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
)
+STATICFILES_FINDERS = [
+ "django.contrib.staticfiles.finders.FileSystemFinder",
+ "django.contrib.staticfiles.finders.AppDirectoriesFinder",
+ "django_assets.finders.AssetsFinder",
+]
+
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
@@ -191,3 +198,6 @@ SHORTPIXEL_API_KEY = os.getenv("SHORTPIXEL_API_KEY")
PLAUSIBLE_DOMAIN = os.getenv("PLAUSIBLE_DOMAIN")
LOGIN_URL = "admin:login"
+
+ASSETS_AUTO_BUILD = DEBUG
+ASSETS_DEBUG = False
diff --git a/poetry.lock b/poetry.lock
index b7dba83..abdfd46 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -82,6 +82,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
[package.extras]
toml = ["toml"]
+[[package]]
+name = "cssmin"
+version = "0.2.0"
+description = "A Python port of the YUI CSS compression algorithm."
+category = "main"
+optional = false
+python-versions = "*"
+
[[package]]
name = "distlib"
version = "0.3.1"
@@ -124,6 +132,18 @@ six = "*"
amazon_ses = ["boto3"]
sparkpost = ["sparkpost"]
+[[package]]
+name = "django-assets"
+version = "2.0"
+description = "Asset management for Django, to compress and merge CSS and Javascript files."
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+Django = ">=1.7"
+webassets = ">=2.0"
+
[[package]]
name = "django-cleanup"
version = "5.1.0"
@@ -465,6 +485,14 @@ six = ">=1.9.0,<2"
docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"]
testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"]
+[[package]]
+name = "webassets"
+version = "2.0"
+description = "Media asset management for Python, with glue code for various web frameworks"
+category = "main"
+optional = false
+python-versions = "*"
+
[[package]]
name = "wrapt"
version = "1.12.1"
@@ -488,7 +516,7 @@ multidict = ">=4.0"
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
-content-hash = "e1764fd2910c5b113fe5346db1e5d5a14c554e716990ab57c2c7618f43a511db"
+content-hash = "29b49600a0a724f59d04d475a305c4f90541753ac0c0896a976feb096bc1b173"
[metadata.files]
appdirs = [
@@ -559,6 +587,9 @@ coverage = [
{file = "coverage-5.3-cp39-cp39-win_amd64.whl", hash = "sha256:47a11bdbd8ada9b7ee628596f9d97fbd3851bd9999d398e9436bd67376dbece7"},
{file = "coverage-5.3.tar.gz", hash = "sha256:280baa8ec489c4f542f8940f9c4c2181f0306a8ee1a54eceba071a449fb870a0"},
]
+cssmin = [
+ {file = "cssmin-0.2.0.tar.gz", hash = "sha256:e012f0cc8401efcf2620332339011564738ae32be8c84b2e43ce8beaec1067b6"},
+]
distlib = [
{file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"},
{file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"},
@@ -571,6 +602,10 @@ django-anymail = [
{file = "django-anymail-7.2.1.tar.gz", hash = "sha256:7fadf9781573b30af5bb6ca2f39b345c4ca2547723ce677c3025292d0a309a96"},
{file = "django_anymail-7.2.1-py2.py3-none-any.whl", hash = "sha256:dc5d835049a5dbf738a0f4bd793c4655cd53ba455e2ead275845bc158d48cc63"},
]
+django-assets = [
+ {file = "django-assets-2.0.tar.gz", hash = "sha256:8abb81e66b4db602bb7b5e5d1f1b5c6511c3e7d8d4804be50bbb77e5ce898639"},
+ {file = "django_assets-2.0-py3-none-any.whl", hash = "sha256:3e4267a453bb6a30a4bcfb4f971a6876a542b5f500167afda892973335c8ac60"},
+]
django-cleanup = [
{file = "django-cleanup-5.1.0.tar.gz", hash = "sha256:8976aec12a22913afb3d1fcb541b1aedde2f5ec243e4260c5ff78bb6aa75a089"},
{file = "django_cleanup-5.1.0-py2.py3-none-any.whl", hash = "sha256:71e098c7d9ac3f3da40b95cff9c0bc51218d40ef419261232f46ba3141c50acc"},
@@ -765,6 +800,10 @@ virtualenv = [
{file = "virtualenv-20.2.1-py2.py3-none-any.whl", hash = "sha256:07cff122e9d343140366055f31be4dcd61fd598c69d11cd33a9d9c8df4546dd7"},
{file = "virtualenv-20.2.1.tar.gz", hash = "sha256:e0aac7525e880a429764cefd3aaaff54afb5d9f25c82627563603f5d7de5a6e5"},
]
+webassets = [
+ {file = "webassets-2.0-py3-none-any.whl", hash = "sha256:a31a55147752ba1b3dc07dee0ad8c8efff274464e08bbdb88c1fd59ffd552724"},
+ {file = "webassets-2.0.tar.gz", hash = "sha256:167132337677c8cedc9705090f6d48da3fb262c8e0b2773b29f3352f050181cd"},
+]
wrapt = [
{file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"},
]
diff --git a/pyproject.toml b/pyproject.toml
index 727bfa3..efe2509 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -31,6 +31,8 @@ pillow = "^7.2"
django-cleanup = "^5.0"
requests = "^2.24"
html2text = "^2020.1.16"
+django-assets = "^2.0"
+cssmin = "^0.2.0"
[tool.poetry.dev-dependencies]
pre-commit = "^2.7"