diff --git a/tests/unit_tests/test_tethys_apps/test_templatetags/test_site_settings.py b/tests/unit_tests/test_tethys_apps/test_templatetags/test_site_settings.py index fb7042e1f..fe6b11fe6 100644 --- a/tests/unit_tests/test_tethys_apps/test_templatetags/test_site_settings.py +++ b/tests/unit_tests/test_tethys_apps/test_templatetags/test_site_settings.py @@ -42,5 +42,23 @@ def test_get_css_is_code(self, mock_isfile, mock_settings): mock_settings.STATIC_ROOT = "test_base_path1" mock_settings.STATICFILES_DIRS = ["test_base_path2"] - ret = ss.load_custom_css("test.css") - self.assertEqual(ret, "") + ret = ss.load_custom_css(".navbar-brand { background-color: darkred; }") + self.assertEqual( + ret, "" + ) + + def test_long_css_text(self): + long_css_text = """ + .site-header { margin: 0 50px 0 0; background-color: red; } + .site-header .navbar-brand { + background-color: darkred; + color: black; + font-style: italic; + font-variant: small-caps; + font-family: cursive; + font-size: 24px; + } + """ + + ret = ss.load_custom_css(long_css_text) + self.assertEqual(ret, f"") diff --git a/tethys_apps/templatetags/site_settings.py b/tethys_apps/templatetags/site_settings.py index c8b7120f4..b85e315aa 100644 --- a/tethys_apps/templatetags/site_settings.py +++ b/tethys_apps/templatetags/site_settings.py @@ -1,28 +1,59 @@ +import logging +from pathlib import Path + from django import template from django.template.defaultfilters import stringfilter from django.conf import settings -from pathlib import Path - from ..static_finders import TethysStaticFinder static_finder = TethysStaticFinder() register = template.Library() +log = logging.getLogger(f"tethys.{__name__}") + @register.filter @stringfilter def load_custom_css(var): + """Load Custom Styles defined in Tethys Portal -> Site Settings + + Args: + var: a filename of CSS to load or CSS text to embed into the page + + Returns: + a string of HTML that either embeds CSS text or points to a file + + """ + if not var.strip(): + return "" if var.startswith("/"): var = var.lstrip("/") - if (Path(settings.STATIC_ROOT) / var).is_file() or static_finder.find(var): - return f'' + try: + # Check if var is a path to a file, if so return a link tag to the file + if (Path(settings.STATIC_ROOT) / var).is_file() or static_finder.find(var): + return f'' - else: for path in settings.STATICFILES_DIRS: if (Path(path) / var).is_file(): return f'' + # If the string is too long for a file path, which could happen if it is CSS, + # an OSError will be raised during the file path checks. This could also happen + # if a lengthy file path is given or is otherwise invalid. + except OSError as e: + oserror_exception = ": " + str(e) + else: + oserror_exception = "" + + # Verify the string is CSS and log warning if it is not + common_css_chars = "{};," + if not any(c in var for c in common_css_chars): + # This appears to be a filename and not a CSS string + log.warning( + "Could not load file '%s' for custom styles%s", var, oserror_exception + ) + return "" return ""