mirror of
https://github.com/sissbruecker/linkding
synced 2024-11-24 20:33:04 +00:00
Add option for custom CSS (#652)
* Add option for adding custom CSS * add missing migration
This commit is contained in:
parent
39782e75e7
commit
83c2530df4
8 changed files with 63 additions and 2 deletions
18
bookmarks/migrations/0026_userprofile_custom_css.py
Normal file
18
bookmarks/migrations/0026_userprofile_custom_css.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 5.0.2 on 2024-03-16 23:05
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("bookmarks", "0025_userprofile_search_preferences"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="userprofile",
|
||||
name="custom_css",
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
|
@ -331,6 +331,7 @@ class UserProfile(models.Model):
|
|||
enable_favicons = models.BooleanField(default=False, null=False)
|
||||
display_url = models.BooleanField(default=False, null=False)
|
||||
permanent_notes = models.BooleanField(default=False, null=False)
|
||||
custom_css = models.TextField(blank=True, null=False)
|
||||
search_preferences = models.JSONField(default=dict, null=False)
|
||||
|
||||
|
||||
|
@ -348,6 +349,7 @@ class UserProfileForm(forms.ModelForm):
|
|||
"enable_favicons",
|
||||
"display_url",
|
||||
"permanent_notes",
|
||||
"custom_css",
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
textarea.custom-css {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.input-group > input[type=submit] {
|
||||
height: auto;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#161822">
|
||||
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#5856e0">
|
||||
{% endif %}
|
||||
{% if request.user_profile.custom_css %}
|
||||
<style>{{ request.user_profile.custom_css }}</style>
|
||||
{% endif %}
|
||||
</head>
|
||||
<body ld-global-shortcuts>
|
||||
|
||||
|
|
|
@ -124,6 +124,18 @@
|
|||
href="{% url 'bookmarks:shared' %}">shared bookmarks page</a>.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<details {% if form.custom_css.value %}open{% endif %}>
|
||||
<summary>Custom CSS</summary>
|
||||
<label for="{{ form.custom_css.id_for_label }}" class="text-assistive">Custom CSS</label>
|
||||
<div class="mt-2">
|
||||
{{ form.custom_css|add_class:"form-input custom-css"|attr:"rows:6" }}
|
||||
</div>
|
||||
</details>
|
||||
<div class="form-input-hint">
|
||||
Allows to add custom CSS to the page.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="submit" name="update_profile" value="Save" class="btn btn-primary mt-2">
|
||||
{% if update_profile_success_message %}
|
||||
|
|
21
bookmarks/tests/test_custom_css.py
Normal file
21
bookmarks/tests/test_custom_css.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from bookmarks.tests.helpers import BookmarkFactoryMixin
|
||||
|
||||
|
||||
class CustomCssTestCase(TestCase, BookmarkFactoryMixin):
|
||||
def setUp(self):
|
||||
self.client.force_login(self.get_or_create_test_user())
|
||||
|
||||
def test_does_not_render_custom_style_tag_by_default(self):
|
||||
response = self.client.get(reverse("bookmarks:index"))
|
||||
self.assertNotContains(response, "<style>")
|
||||
|
||||
def test_renders_custom_style_tag_if_user_has_custom_css(self):
|
||||
profile = self.get_or_create_test_user().profile
|
||||
profile.custom_css = "body { background-color: red; }"
|
||||
profile.save()
|
||||
|
||||
response = self.client.get(reverse("bookmarks:index"))
|
||||
self.assertContains(response, "<style>body { background-color: red; }</style>")
|
|
@ -32,6 +32,7 @@ class SettingsGeneralViewTestCase(TestCase, BookmarkFactoryMixin):
|
|||
"tag_search": UserProfile.TAG_SEARCH_STRICT,
|
||||
"display_url": False,
|
||||
"permanent_notes": False,
|
||||
"custom_css": "",
|
||||
}
|
||||
|
||||
return {**form_data, **overrides}
|
||||
|
@ -63,6 +64,7 @@ class SettingsGeneralViewTestCase(TestCase, BookmarkFactoryMixin):
|
|||
"tag_search": UserProfile.TAG_SEARCH_LAX,
|
||||
"display_url": True,
|
||||
"permanent_notes": True,
|
||||
"custom_css": "body { background-color: #000; }",
|
||||
}
|
||||
response = self.client.post(reverse("bookmarks:settings.general"), form_data)
|
||||
html = response.content.decode()
|
||||
|
@ -93,6 +95,7 @@ class SettingsGeneralViewTestCase(TestCase, BookmarkFactoryMixin):
|
|||
self.assertEqual(
|
||||
self.user.profile.permanent_notes, form_data["permanent_notes"]
|
||||
)
|
||||
self.assertEqual(self.user.profile.custom_css, form_data["custom_css"])
|
||||
self.assertInHTML(
|
||||
"""
|
||||
<p class="form-input-hint">Profile updated</p>
|
||||
|
|
|
@ -131,8 +131,6 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static")
|
|||
|
||||
# Turn off SASS compilation by default
|
||||
SASS_PROCESSOR_ENABLED = False
|
||||
# Location where generated CSS files are saved
|
||||
SASS_PROCESSOR_ROOT = os.path.join(BASE_DIR, "bookmarks", "static")
|
||||
|
||||
# Add SASS preprocessor finder to resolve generated CSS
|
||||
STATICFILES_FINDERS = [
|
||||
|
|
Loading…
Reference in a new issue