From 3219e5397e8e6a2377f32d4bffb74b4ef4f5bfdb Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 13 Sep 2024 16:05:01 -0500 Subject: [PATCH 01/60] feat: support multisite --- taccsite_cms/custom_app_settings.example.py | 2 +- taccsite_cms/middleware/settings.py | 20 ++++++++++++++++++++ taccsite_cms/settings_local.example.py | 4 ++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 taccsite_cms/middleware/settings.py diff --git a/taccsite_cms/custom_app_settings.example.py b/taccsite_cms/custom_app_settings.example.py index 3ac04c50d..46ab65ef9 100644 --- a/taccsite_cms/custom_app_settings.example.py +++ b/taccsite_cms/custom_app_settings.example.py @@ -1,3 +1,3 @@ CUSTOM_APPS = ['apps.custom_example'] -CUSTOM_MIDDLEWARE = [] +CUSTOM_MIDDLEWARE = ['taccsite_cms.middleware.settings.SiteIdMiddleware'] STATICFILES_DIRS = () diff --git a/taccsite_cms/middleware/settings.py b/taccsite_cms/middleware/settings.py new file mode 100644 index 000000000..0c2f3ff14 --- /dev/null +++ b/taccsite_cms/middleware/settings.py @@ -0,0 +1,20 @@ +"""Change site based on domain name (fallback to default site)""" +from django.conf import settings +from urllib.parse import urlparse +from django.contrib.sites.models import Site + +class SiteIdMiddleware: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + try: + current_site = Site.objects.get(domain=request.get_host()) + except Site.DoesNotExist: + current_site = Site.objects.get(id=settings.DEFAULT_SITE_ID) + + request.current_site = current_site + settings.SITE_ID = current_site.id + + response = self.get_response(request) + return response diff --git a/taccsite_cms/settings_local.example.py b/taccsite_cms/settings_local.example.py index 016656def..22774e8fe 100644 --- a/taccsite_cms/settings_local.example.py +++ b/taccsite_cms/settings_local.example.py @@ -22,3 +22,7 @@ # To disable the Core-Portal integration PORTAL_IS_TACC_CORE_PORTAL = False PORTAL_HAS_LOGIN = False + +# To allow login in unique situations +# FAQ: If `BLOG_MULTISITE = True`, set `SESSION_COOKIE_SECURE=False` to be able to log in to CMS Admin at different domain (e.g. 0.0.0.0) +SESSION_COOKIE_SECURE = False From eeb4df82f8bca2b7f40a838dfa16271670ad1b73 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 15 May 2025 21:13:35 +0000 Subject: [PATCH 02/60] refactor: simplify and rename middleware --- taccsite_cms/custom_app_settings.example.py | 2 +- taccsite_cms/middleware/settings.py | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/taccsite_cms/custom_app_settings.example.py b/taccsite_cms/custom_app_settings.example.py index 1fd0c64c8..620484bf7 100644 --- a/taccsite_cms/custom_app_settings.example.py +++ b/taccsite_cms/custom_app_settings.example.py @@ -12,6 +12,6 @@ ] CUSTOM_MIDDLEWARE = [ - 'taccsite_cms.middleware.settings.SiteIdMiddleware' + 'taccsite_cms.middleware.settings.DynamicSiteIdMiddleware' ] STATICFILES_DIRS = () diff --git a/taccsite_cms/middleware/settings.py b/taccsite_cms/middleware/settings.py index 0c2f3ff14..be2cc28b2 100644 --- a/taccsite_cms/middleware/settings.py +++ b/taccsite_cms/middleware/settings.py @@ -1,20 +1,18 @@ """Change site based on domain name (fallback to default site)""" from django.conf import settings -from urllib.parse import urlparse from django.contrib.sites.models import Site -class SiteIdMiddleware: +class DynamicSiteIdMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): try: - current_site = Site.objects.get(domain=request.get_host()) + host = request.get_host() + site = Site.objects.get(domain=host) + settings.SITE_ID = site.id except Site.DoesNotExist: - current_site = Site.objects.get(id=settings.DEFAULT_SITE_ID) - - request.current_site = current_site - settings.SITE_ID = current_site.id + settings.SITE_ID = getattr(settings, 'DEFAULT_SITE_ID', 1) response = self.get_response(request) return response From 3a1e28e381bff1a7155e32b6402fde80b5928988 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 21 Jul 2025 17:46:06 -0500 Subject: [PATCH 03/60] fix: inaccurate text picture template name (#967) * fix: inaccurate text picture template name * fix: show value if old template is in use --- taccsite_cms/settings.py | 3 +- .../no_link_to_ext_image/picture.html | 30 ++----------------- .../no_link_to_image/picture.html | 28 +++++++++++++++++ 3 files changed, 32 insertions(+), 29 deletions(-) create mode 100644 taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index ed6927309..335f094a8 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -580,7 +580,8 @@ def get_subdirs_as_module_names(path): ('center', _('Align center')), ] DJANGOCMS_PICTURE_TEMPLATES = [ - ('no_link_to_ext_image', _('Do not link to external image')), + ('no_link_to_image', _('Do not link to image to itself')), + ('no_link_to_ext_image', _('Do not link to image to itself (DEPRECATED)')), ] # FILE UPLOAD VALUES MUST BE SET! diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html index 479af2ce9..02d1d1e97 100644 --- a/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html @@ -1,28 +1,2 @@ -{% extends "djangocms_picture/default/picture.html" %} -{# Do not let instance.external_picture trigger picture_link templating #} -{% comment %} -App djangocms_picture assumes external image must be linked to, -but we want to allow external image to be displayed without link. -{% endcomment %} -{# FAQ: picture_link is instance link_url or link_page_id or external_picture #} -{# https://github.com/django-cms/djangocms-picture/blob/3.0.0/djangocms_picture/models.py#L269-L276 #} - -{# So picture with external image is not wrapped in a link #} -{% block picture_link_start %} - {% if instance.link_url or instance.link_page_id %} - {% block picture_link %} - {{ block.super }} - {% endblock %} - {% endif %} -{% endblock %} - -{# So picture attributes can be added to picture with external image #} -{% block picture_attributes %} - {% if not instance.caption_text and not instance.link_url and not instance.link_page_id and not instance.child_plugin_instances %} - {{ instance.attributes_str }} - {% endif %} -{% endblock %} - -{# So picture with external image is not wrapped in a link #} -{% block picture_link_end %} -{% endblock %} +{# backwards-compatibility for old name #} +{% extends "../no_link_to_image/picture.html" %} diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html new file mode 100644 index 000000000..479af2ce9 --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html @@ -0,0 +1,28 @@ +{% extends "djangocms_picture/default/picture.html" %} +{# Do not let instance.external_picture trigger picture_link templating #} +{% comment %} +App djangocms_picture assumes external image must be linked to, +but we want to allow external image to be displayed without link. +{% endcomment %} +{# FAQ: picture_link is instance link_url or link_page_id or external_picture #} +{# https://github.com/django-cms/djangocms-picture/blob/3.0.0/djangocms_picture/models.py#L269-L276 #} + +{# So picture with external image is not wrapped in a link #} +{% block picture_link_start %} + {% if instance.link_url or instance.link_page_id %} + {% block picture_link %} + {{ block.super }} + {% endblock %} + {% endif %} +{% endblock %} + +{# So picture attributes can be added to picture with external image #} +{% block picture_attributes %} + {% if not instance.caption_text and not instance.link_url and not instance.link_page_id and not instance.child_plugin_instances %} + {{ instance.attributes_str }} + {% endif %} +{% endblock %} + +{# So picture with external image is not wrapped in a link #} +{% block picture_link_end %} +{% endblock %} From 893a434c0b07933fcf446be4dcec4002eff90726 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 21 Jul 2025 20:41:47 -0500 Subject: [PATCH 04/60] refactor: no_link_to_image --- taccsite_cms/settings.py | 4 ++-- .../djangocms_picture/no_link_to_ext_image/picture.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 335f094a8..1b8c026c0 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -580,8 +580,8 @@ def get_subdirs_as_module_names(path): ('center', _('Align center')), ] DJANGOCMS_PICTURE_TEMPLATES = [ - ('no_link_to_image', _('Do not link to image to itself')), - ('no_link_to_ext_image', _('Do not link to image to itself (DEPRECATED)')), + ('no_link_to_image', _('Do not link image to itself')), + ('no_link_to_ext_image', _('Do not link image to itself (DEPRECATED)')), ] # FILE UPLOAD VALUES MUST BE SET! diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html index 02d1d1e97..55b62f679 100644 --- a/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html @@ -1,2 +1,2 @@ -{# backwards-compatibility for old name #} -{% extends "../no_link_to_image/picture.html" %} +{# backwards-compatibility for old name #} +{% extends "djangocms_picture/no_link_to_image/picture.html" %} From 91cc70c7712f15b0531f99f01ecd02e2e99efd32 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:13:57 -0500 Subject: [PATCH 05/60] docs: simplify no_link_to_image/picture.html notes --- .../djangocms_picture/no_link_to_image/picture.html | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html index 479af2ce9..c56826db6 100644 --- a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html @@ -1,11 +1,6 @@ {% extends "djangocms_picture/default/picture.html" %} -{# Do not let instance.external_picture trigger picture_link templating #} -{% comment %} -App djangocms_picture assumes external image must be linked to, -but we want to allow external image to be displayed without link. -{% endcomment %} -{# FAQ: picture_link is instance link_url or link_page_id or external_picture #} -{# https://github.com/django-cms/djangocms-picture/blob/3.0.0/djangocms_picture/models.py#L269-L276 #} +{# To allow image to be rendered without a link #} +{# FAQ: App djangocms_picture assumes that an image, if not explicitely linked, must link to itself. But sometimes, we want an image to just be an image, unlinked. #} {# So picture with external image is not wrapped in a link #} {% block picture_link_start %} From 8cbb4a9a0b46a5574fb750ebecd37c742083f07b Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:15:17 -0500 Subject: [PATCH 06/60] docs: clarify no_link_to_image/picture.html notes --- .../djangocms_picture/no_link_to_image/picture.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html index c56826db6..1aa0ed869 100644 --- a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html @@ -2,7 +2,7 @@ {# To allow image to be rendered without a link #} {# FAQ: App djangocms_picture assumes that an image, if not explicitely linked, must link to itself. But sometimes, we want an image to just be an image, unlinked. #} -{# So picture with external image is not wrapped in a link #} +{# So picture is not wrapped in a link #} {% block picture_link_start %} {% if instance.link_url or instance.link_page_id %} {% block picture_link %} @@ -11,13 +11,13 @@ {% endif %} {% endblock %} -{# So picture attributes can be added to picture with external image #} +{# So picture attributes are added to unlinked picture #} {% block picture_attributes %} {% if not instance.caption_text and not instance.link_url and not instance.link_page_id and not instance.child_plugin_instances %} {{ instance.attributes_str }} {% endif %} {% endblock %} -{# So picture with external image is not wrapped in a link #} +{# So picture is not wrapped in a link #} {% block picture_link_end %} {% endblock %} From 6d7b730ed4a8a8f25c1876c30252ecc96f00910e Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 22 Jul 2025 11:40:05 -0500 Subject: [PATCH 07/60] docs: djangocms_picture template indentation --- .../templates/djangocms_picture/default/picture.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/taccsite_cms/templates/djangocms_picture/default/picture.html b/taccsite_cms/templates/djangocms_picture/default/picture.html index 15f50ab31..a06dc8093 100644 --- a/taccsite_cms/templates/djangocms_picture/default/picture.html +++ b/taccsite_cms/templates/djangocms_picture/default/picture.html @@ -19,9 +19,9 @@ {{ instance.attributes_str }} {# /TACC #} {{ instance.link_attributes_str }}> -{# TACC (allow link to be conditional): #} -{% endblock %} -{# /TACC #} + {# TACC (allow link to be conditional): #} + {% endblock %} + {# /TACC #} {% endif %} {# TACC (allow link to be conditional): #} {% endblock %} From 7f3ec2106a6dbb0fec209c4946d9c892f50be856 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 25 Jul 2025 13:15:37 -0500 Subject: [PATCH 08/60] feat: support core-styles u-image-zoom (#968) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: support core-styles u-image-zoom * feat: support core-styles u-image-zoom via script * Revert "feat: support core-styles u-image-zoom via script" This reverts commit 2a15a75f5cdd718ec4191d656cf200172fdeaba1. * feat: support zoom_effect + no_link_to_image * refactor: only load css once from multiple tries * refactor: extract link & figure start to templates * refactor: rebuild zoom templates to strip classes * feat: template tag `strip_class_attribute` * fix: strip_class_attribute munges data-class test * fix: template name/path typo * fix: all picture template bugs i think * docs: add help_text to Picture template field * feat: overwrite bs4 picture plugin validation * fix: strip_class_attr… regex munges `data-class` * test: highlight unsupported figure image zoom * fix: u-image-zoom-- class not added * fix: sometimes span missing & class in wrong spot * fix: core-styles zoom bug * enhance: clearer debuging ui * refactor: template logic → custom view context * Revert "refactor: template logic → custom view context" This reverts commit a12356870decb3341347a74f7d8d985ffd309f22. --- taccsite_cms/apps.py | 4 + .../cms_plugins.py | 23 ---- taccsite_cms/djangocms_picture/extend.py | 107 ++++++++++++++++++ taccsite_cms/settings.py | 3 +- .../djangocms_picture/default/picture.html | 36 +++--- .../default/picture_link_start.html | 18 +++ .../no_link_to_image/picture.html | 7 +- .../zoom_effect/picture.html | 24 ++++ .../zoom_effect/zoom_asset.html | 7 ++ .../zoom_effect/zoom_wrapper_end.html | 1 + .../zoom_effect/zoom_wrapper_start.html | 1 + .../zoom_effect_no_link_to_image/picture.html | 30 +++++ .../test/css-image-picture-block.html | 74 ++++++++++++ .../templatetags/strip_class_attribute.py | 22 ++++ 14 files changed, 315 insertions(+), 42 deletions(-) delete mode 100644 taccsite_cms/contrib/bootstrap4_djangocms_picture/cms_plugins.py create mode 100644 taccsite_cms/djangocms_picture/extend.py create mode 100644 taccsite_cms/templates/djangocms_picture/default/picture_link_start.html create mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html create mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_asset.html create mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html create mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html create mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html create mode 100644 taccsite_cms/templates/snippets/test/css-image-picture-block.html create mode 100644 taccsite_cms/templatetags/strip_class_attribute.py diff --git a/taccsite_cms/apps.py b/taccsite_cms/apps.py index f3bdc022a..64d8e4bde 100644 --- a/taccsite_cms/apps.py +++ b/taccsite_cms/apps.py @@ -1,7 +1,10 @@ import logging + from django.apps import AppConfig from django.db.models.signals import post_migrate +from .djangocms_picture.extend import extendPicturePlugin + logger = logging.getLogger(f"portal.{__name__}") class TaccsiteCmsConfig(AppConfig): @@ -10,6 +13,7 @@ class TaccsiteCmsConfig(AppConfig): def ready(self): post_migrate.connect(self.create_groups, sender=self) + extendPicturePlugin() def create_groups(self, sender, **kwargs): from django.contrib.auth.models import Group diff --git a/taccsite_cms/contrib/bootstrap4_djangocms_picture/cms_plugins.py b/taccsite_cms/contrib/bootstrap4_djangocms_picture/cms_plugins.py deleted file mode 100644 index 3edf41136..000000000 --- a/taccsite_cms/contrib/bootstrap4_djangocms_picture/cms_plugins.py +++ /dev/null @@ -1,23 +0,0 @@ -# To support generic Image plugin without uninstalling Bootstrap's -# FAQ: Bootstrap Image plugin has features not desirable in TACC plugins -# FAQ: We must not break sites that already use Bootstrap Image plugin -try: - from django.utils.translation import gettext as _ - - from cms.plugin_pool import plugin_pool - - from djangocms_picture.cms_plugins import PicturePlugin - from djangocms_bootstrap4.contrib.bootstrap4_picture.cms_plugins import Bootstrap4PicturePlugin - - # To clairfy for users how this plugin differs from Generic > Image - Bootstrap4PicturePlugin.name = _('Picture / Image (Responsive)') - - # To re-register generic Picture plugin - # SEE: https://github.com/django-cms/djangocms-bootstrap4/blob/master/djangocms_bootstrap4/contrib/bootstrap4_picture/cms_plugins.py#L54 - plugin_pool.register_plugin(PicturePlugin) - -# To avoid server crash if Boostrap plugin is not registered -# CAVEAT: If import statement fails for reason other than Bootstrap presence, -# then that failure, and the failure of this plugin, is silent -except ImportError: - pass diff --git a/taccsite_cms/djangocms_picture/extend.py b/taccsite_cms/djangocms_picture/extend.py new file mode 100644 index 000000000..6e93159e9 --- /dev/null +++ b/taccsite_cms/djangocms_picture/extend.py @@ -0,0 +1,107 @@ +import logging + +logger = logging.getLogger(f"django.{__name__}") + +def extendPicturePlugin(): + from django.core.exceptions import ValidationError + from django.utils.translation import gettext_lazy as _ + + from cms.plugin_pool import plugin_pool + + from djangocms_link.cms_plugins import LinkPlugin + + ZOOM_TEMPLATE_NAME_PREFIX = 'zoom' + ZOOM_TEMPLATE_LABEL = 'Zoom image on hover' + ZOOM_TEMPLATE_NOTE = _('The "%(zoom_template_label)s" templates only have effect if Image either has a Link or is within a Link.') % {"zoom_template_label": ZOOM_TEMPLATE_LABEL} + ZOOM_TEMPLATE_ERROR = _(' "%(zoom_template_label)s" templates require Image to either have a Link or be within a Link.') % {"zoom_template_label": ZOOM_TEMPLATE_LABEL} + + logger.info("Extending PicturePlugin (and Bootstrap4PicturePlugin)...") + + def add_help_text(form_instance): + """Adds help text for: 'Template' field""" + + if 'template' in form_instance.fields: + form_instance.fields['template'].help_text += _(' %(ZOOM_TEMPLATE_NOTE)s') % {"ZOOM_TEMPLATE_NOTE": ZOOM_TEMPLATE_NOTE} + + + def validate_zoom_template(instance): + """Validates: 'Template' field choice 'Zoom image …'""" + + errors = {} + + has_picture_link = bool(instance.link_url or instance.link_page_id) + use_zoom_template = ZOOM_TEMPLATE_NAME_PREFIX in instance.template + parent_plugin = instance.parent.get_plugin_instance()[0] if instance.parent else None + is_in_link = isinstance(parent_plugin, LinkPlugin) if parent_plugin else False + + logger.info(f'validate_zoom_template: %s', { + 'link': instance.link_url or instance.link_page_id, + 'has_picture_link' : has_picture_link, + 'use_zoom_template' : use_zoom_template, + 'is_in_link': is_in_link, + }) + + if (use_zoom_template and not has_picture_link and not is_in_link ): + errors['template'] = ZOOM_TEMPLATE_ERROR + + if errors: + raise ValidationError(errors) + + + # djangocms_picture + from djangocms_picture.cms_plugins import PicturePlugin as OriginalPicturePlugin + from djangocms_picture.models import Picture as OriginalPicture + + class PicturePluginForm(OriginalPicturePlugin.form): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + add_help_text(self) + + class PicturePluginModel(OriginalPicture): + class Meta: + proxy = True + + def clean(self): + super().clean() + validate_zoom_template(self) + + class PicturePlugin(OriginalPicturePlugin): + model = PicturePluginModel + form = PicturePluginForm + name = 'Image' + + # To support generic Image plugin without uninstalling Bootstrap's + # FAQ: Had been done cuz Image plugin had percieved use cases, + # but is since not regularly used, but is used, thus maintained + # FAQ: No need to unregister cuz Bootstrap4PicturePlugin does that + # https://github.com/django-cms/djangocms-bootstrap4/blob/3.0.0/djangocms_bootstrap4/contrib/bootstrap4_picture/cms_plugins.py#L54 + # plugin_pool.unregister_plugin(OriginalPicturePlugin) + plugin_pool.register_plugin(PicturePlugin) + + + # djangocms_bootstrap4: bootstrap4_picture + from djangocms_bootstrap4.contrib.bootstrap4_picture.cms_plugins import Bootstrap4PicturePlugin as OriginalBootstrap4PicturePlugin + from djangocms_bootstrap4.contrib.bootstrap4_picture.models import Bootstrap4Picture as OriginalBootstrap4Picture + + class Bootstrap4PictureForm(OriginalBootstrap4PicturePlugin.form): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + add_help_text(self) + + class Bootstrap4PictureModel(OriginalBootstrap4Picture): + class Meta: + proxy = True + + def clean(self): + super().clean() + validate_zoom_template(self) + + class Bootstrap4PicturePlugin(OriginalBootstrap4PicturePlugin): + model = Bootstrap4PictureModel + form = Bootstrap4PictureForm + name = 'Picture / Image (Responsive)' + + plugin_pool.unregister_plugin(OriginalBootstrap4PicturePlugin) + plugin_pool.register_plugin(Bootstrap4PicturePlugin) + + logger.info("Extended PicturePlugin (and Bootstrap4PicturePlugin).") diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 1b8c026c0..41b59a56c 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -481,7 +481,6 @@ def gettext(s): return s # django CMS Bootstrap # IDEA: Extend Bootstrap apps instead of overwrite 'taccsite_cms.contrib.bootstrap4_djangocms_link', - 'taccsite_cms.contrib.bootstrap4_djangocms_picture', # TACC CMS Plugins 'djangocms_tacc_image_gallery', @@ -582,6 +581,8 @@ def get_subdirs_as_module_names(path): DJANGOCMS_PICTURE_TEMPLATES = [ ('no_link_to_image', _('Do not link image to itself')), ('no_link_to_ext_image', _('Do not link image to itself (DEPRECATED)')), + ('zoom_effect', _('Zoom image on hover')), + ('zoom_effect_no_link_to_image', _('Zoom image on hover & Do not link image to itself')), ] # FILE UPLOAD VALUES MUST BE SET! diff --git a/taccsite_cms/templates/djangocms_picture/default/picture.html b/taccsite_cms/templates/djangocms_picture/default/picture.html index a06dc8093..ddcf3db2b 100644 --- a/taccsite_cms/templates/djangocms_picture/default/picture.html +++ b/taccsite_cms/templates/djangocms_picture/default/picture.html @@ -10,36 +10,34 @@ {% block picture_link_start %} {# /TACC #} {% if picture_link %} - {# TACC (allow link to be conditional): #} - {% block picture_link %} - {# /TACC #} - - {# TACC (allow link to be conditional): #} - {% endblock %} + {% include "djangocms_picture/default/picture_link_start.html" %} {# /TACC #} {% endif %} {# TACC (allow link to be conditional): #} {% endblock %} {# /TACC #} -{# start render figure/figcaption #} +{# TACC (allow figure to be overridden): #} +{% block picture_figure_start %} +{# /TACC #} {# TACC (support children as caption content): #} {# {% if instance.caption_text %} #} {% if instance.caption_text or instance.child_plugin_instances %} {# TACC (assign attributes to parent): #} - {#
#}
{# /TACC #} {% endif %} {# /TACC #} -{# end render figure/figcaption #} +{# TACC (allow figure to be overridden): #} +{% endblock %} +{# /TACC #} +{# TACC (allow image wrapper): #} +{% block picture_wrap_start %} +{% endblock picture_wrap_start %} +{# /TACC #} {# TACC (mimic v3.0.0 to v4.0.0 changes): #} {% localize off %} {# /TACC #} @@ -74,8 +72,14 @@ {# TACC (mimic v3.0.0 to v4.0.0 changes): #} {% endlocalize %} {# /TACC #} +{# TACC (allow_image_wrapper): #} +{% block picture_wrap_end %} +{% endblock picture_wrap_end %} +{# /TACC #} -{# start render figure/figcaption #} +{# TACC (allow figure to be overridden): #} +{% block picture_figure_end %} +{# /TACC #} {# {% if instance.caption_text %} #} {% if instance.caption_text or instance.child_plugin_instances %} {# TACC (support children as caption content): #} @@ -89,7 +93,9 @@ {# /TACC #}
{% endif %} -{# end render figure/figcaption #} +{# TACC (allow figure to be overridden): #} +{% endblock %} +{# /TACC #} {# TACC (allow link to be conditional): #} {% block picture_link_end %} diff --git a/taccsite_cms/templates/djangocms_picture/default/picture_link_start.html b/taccsite_cms/templates/djangocms_picture/default/picture_link_start.html new file mode 100644 index 000000000..fb2c5a0a4 --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/default/picture_link_start.html @@ -0,0 +1,18 @@ +{# https://github.com/django-cms/djangocms-picture/blob/3.0.0/djangocms_picture/templates/djangocms_picture/default/picture.html#L4-L6 #} + +{# @var className #} +{% load strip_class_attribute %} + +
diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html index 1aa0ed869..ad60a5d4c 100644 --- a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html @@ -5,9 +5,7 @@ {# So picture is not wrapped in a link #} {% block picture_link_start %} {% if instance.link_url or instance.link_page_id %} - {% block picture_link %} - {{ block.super }} - {% endblock %} + {% include "djangocms_picture/default/picture_link_start.html" %} {% endif %} {% endblock %} @@ -20,4 +18,7 @@ {# So picture is not wrapped in a link #} {% block picture_link_end %} + {% if instance.link_url or instance.link_page_id %} + + {% endif %} {% endblock %} diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html b/taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html new file mode 100644 index 000000000..993517ec0 --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html @@ -0,0 +1,24 @@ +{% extends "djangocms_picture/default/picture.html" %} + +{# Add u-image-zoom class on link if link is present without figure #} +{% block picture_link_start %} + {% if picture_link and not instance.caption_text and not instance.child_plugin_instances %} + {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} + {% include "djangocms_picture/default/picture_link_start.html" with className="u-image-zoom--on-hover" %} + {% else %} + {{ block.super }} + {% endif %} +{% endblock %} + +{# Add u-image-zoom class on image wrapper if no link #} +{% block picture_wrap_start %} + {% if instance.caption_text or instance.child_plugin_instances or not picture_link %} + {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} + {% include "djangocms_picture/zoom_effect/zoom_wrapper_start.html" %} + {% endif %} +{% endblock %} +{% block picture_wrap_end %} + {% if instance.caption_text or instance.child_plugin_instances or not picture_link %} + {% include "djangocms_picture/zoom_effect/zoom_wrapper_end.html" %} + {% endif %} +{% endblock %} diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_asset.html b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_asset.html new file mode 100644 index 000000000..230e3e264 --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_asset.html @@ -0,0 +1,7 @@ +{% load sekizai_tags %} + +{% addtoblock "css" %} + +{% endaddtoblock %} diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html new file mode 100644 index 000000000..294567489 --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html @@ -0,0 +1 @@ + diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html new file mode 100644 index 000000000..7998a3d33 --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html @@ -0,0 +1 @@ + diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html b/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html new file mode 100644 index 000000000..c882de1cf --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html @@ -0,0 +1,30 @@ +{% extends "djangocms_picture/no_link_to_image/picture.html" %} + +{# Add u-image-zoom class on link if link is present without figure #} +{% block picture_link_start %} + {% if instance.link_url or instance.link_page_id %} + {% if not instance.caption_text and not instance.child_plugin_instances %} + {% include "djangocms_picture/default/picture_link_start.html" with className="u-image-zoom--on-hover" %} + {% else %} + {{ block.super }} + {% endif %} + {% else %} + {{ block.super }} + {% endif %} +{% endblock %} + +{# Add u-image-zoom class on image wrapper if no link and no figure #} +{% block picture_wrap_start %} + {% if instance.caption_text or instance.child_plugin_instances %} + {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} + {% include "djangocms_picture/zoom_effect/zoom_wrapper_start.html" %} + {% elif not instance.link_url and not instance.link_page_id %} + {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} + {% include "djangocms_picture/zoom_effect/zoom_wrapper_start.html" %} + {% endif %} +{% endblock %} +{% block picture_wrap_end %} + {% if instance.caption_text or instance.child_plugin_instances or not instance.link_url and not instance.link_page_id %} + {% include "djangocms_picture/zoom_effect/zoom_wrapper_end.html" %} + {% endif %} +{% endblock %} diff --git a/taccsite_cms/templates/snippets/test/css-image-picture-block.html b/taccsite_cms/templates/snippets/test/css-image-picture-block.html new file mode 100644 index 000000000..78e4b70df --- /dev/null +++ b/taccsite_cms/templates/snippets/test/css-image-picture-block.html @@ -0,0 +1,74 @@ + diff --git a/taccsite_cms/templatetags/strip_class_attribute.py b/taccsite_cms/templatetags/strip_class_attribute.py new file mode 100644 index 000000000..24a55b428 --- /dev/null +++ b/taccsite_cms/templatetags/strip_class_attribute.py @@ -0,0 +1,22 @@ +from django import template +import re + +register = template.Library() + +@register.filter +def strip_class_attribute(attributes_str): + """ + Remove class attribute from an HTML attributes string. + Usage: {{ instance.attributes_str|strip_class_attribute|safe }} + """ + if not attributes_str: + return "" + + # To remove `class="…"` or anything equivalent + pattern = r'(? Date: Fri, 25 Jul 2025 20:36:57 -0500 Subject: [PATCH 09/60] refactor!: djangocms_picture extension (#969) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: support core-styles u-image-zoom * feat: support core-styles u-image-zoom via script * Revert "feat: support core-styles u-image-zoom via script" This reverts commit 2a15a75f5cdd718ec4191d656cf200172fdeaba1. * feat: support zoom_effect + no_link_to_image * refactor: only load css once from multiple tries * refactor: extract link & figure start to templates * refactor: rebuild zoom templates to strip classes * feat: template tag `strip_class_attribute` * fix: strip_class_attribute munges data-class test * fix: template name/path typo * fix: all picture template bugs i think * docs: add help_text to Picture template field * feat: overwrite bs4 picture plugin validation * fix: strip_class_attr… regex munges `data-class` * test: highlight unsupported figure image zoom * fix: u-image-zoom-- class not added * fix: sometimes span missing & class in wrong spot * fix: core-styles zoom bug * enhance: clearer debuging ui * refactor: template logic → custom view context * Revert "refactor: template logic → custom view context" This reverts commit a12356870decb3341347a74f7d8d985ffd309f22. * refactor: template logic → custom view context * fix: bad/old path to zoom asset * refactor: move css snippet to stylehseet * refactor: rename test stylesheet * fix: test stylesheet too specific * fix: a lot, and simplify * refactor!: revert template names * fix: final bugs * chore: remove excess new line * refactor: simplify templates and update comments --- taccsite_cms/djangocms_picture/extend.py | 99 +++++++++++++++---- taccsite_cms/settings.py | 5 +- .../site_cms/css/test/djangocms-picture.css} | 4 +- .../djangocms_picture/default/picture.html | 81 +++++++-------- .../default/picture_link_start.html | 18 ---- .../{zoom_effect => default}/zoom_asset.html | 0 .../no_link_to_ext_image/picture.html | 8 +- .../no_link_to_image/picture.html | 26 +---- .../zoom_effect/picture.html | 25 +---- .../zoom_effect/zoom_wrapper_end.html | 1 - .../zoom_effect/zoom_wrapper_start.html | 1 - .../picture.html | 5 + .../zoom_effect_no_link_to_image/picture.html | 30 ------ 13 files changed, 142 insertions(+), 161 deletions(-) rename taccsite_cms/{templates/snippets/test/css-image-picture-block.html => static/site_cms/css/test/djangocms-picture.css} (94%) delete mode 100644 taccsite_cms/templates/djangocms_picture/default/picture_link_start.html rename taccsite_cms/templates/djangocms_picture/{zoom_effect => default}/zoom_asset.html (100%) delete mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html delete mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html create mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_ext_image/picture.html delete mode 100644 taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html diff --git a/taccsite_cms/djangocms_picture/extend.py b/taccsite_cms/djangocms_picture/extend.py index 6e93159e9..2d2292b38 100644 --- a/taccsite_cms/djangocms_picture/extend.py +++ b/taccsite_cms/djangocms_picture/extend.py @@ -1,7 +1,3 @@ -import logging - -logger = logging.getLogger(f"django.{__name__}") - def extendPicturePlugin(): from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ @@ -10,12 +6,12 @@ def extendPicturePlugin(): from djangocms_link.cms_plugins import LinkPlugin - ZOOM_TEMPLATE_NAME_PREFIX = 'zoom' + ZOOM_TEMPLATE_NAME = 'zoom_effect' ZOOM_TEMPLATE_LABEL = 'Zoom image on hover' ZOOM_TEMPLATE_NOTE = _('The "%(zoom_template_label)s" templates only have effect if Image either has a Link or is within a Link.') % {"zoom_template_label": ZOOM_TEMPLATE_LABEL} ZOOM_TEMPLATE_ERROR = _(' "%(zoom_template_label)s" templates require Image to either have a Link or be within a Link.') % {"zoom_template_label": ZOOM_TEMPLATE_LABEL} - logger.info("Extending PicturePlugin (and Bootstrap4PicturePlugin)...") + LINK_TEMPLATE_NAME = 'no_link_to_ext_image' def add_help_text(form_instance): """Adds help text for: 'Template' field""" @@ -23,30 +19,83 @@ def add_help_text(form_instance): if 'template' in form_instance.fields: form_instance.fields['template'].help_text += _(' %(ZOOM_TEMPLATE_NOTE)s') % {"ZOOM_TEMPLATE_NOTE": ZOOM_TEMPLATE_NOTE} + def whether_to_render_link(instance): + has_explicit_link = bool(instance.link_url or instance.link_page_id) + # FAQ: The djangocms_picture has "feature" such that an image with + # "External image" URL will automatically link to that resource + has_implicit_link = bool(instance.get_link()) and not has_explicit_link + + allow_implicit_link = not LINK_TEMPLATE_NAME in instance.template + + if has_explicit_link or (has_implicit_link and allow_implicit_link): + return True + + return False def validate_zoom_template(instance): """Validates: 'Template' field choice 'Zoom image …'""" errors = {} - has_picture_link = bool(instance.link_url or instance.link_page_id) - use_zoom_template = ZOOM_TEMPLATE_NAME_PREFIX in instance.template + would_render_link = whether_to_render_link(instance) + should_add_zoom_effect = ZOOM_TEMPLATE_NAME in instance.template parent_plugin = instance.parent.get_plugin_instance()[0] if instance.parent else None is_in_link = isinstance(parent_plugin, LinkPlugin) if parent_plugin else False - logger.info(f'validate_zoom_template: %s', { - 'link': instance.link_url or instance.link_page_id, - 'has_picture_link' : has_picture_link, - 'use_zoom_template' : use_zoom_template, - 'is_in_link': is_in_link, - }) - - if (use_zoom_template and not has_picture_link and not is_in_link ): + if (should_add_zoom_effect and not would_render_link and not is_in_link): errors['template'] = ZOOM_TEMPLATE_ERROR if errors: raise ValidationError(errors) + def get_more_context_variables(instance): + """ + Calculate boolean context variables to simplify template logic. + Returns a dictionary of context variables. + """ + # Link (set 1) + has_explicit_link = bool(instance.get_link()) + parent_plugin = instance.parent.get_plugin_instance()[0] if instance.parent else None + is_in_link_plugin = isinstance(parent_plugin, LinkPlugin) if parent_plugin else False + has_any_link = has_explicit_link or is_in_link_plugin + + # Figure/Caption + has_caption_text = bool(instance.caption_text) + has_child_plugins = bool(instance.child_plugin_instances) + has_figure_content = has_caption_text or has_child_plugins + + # Template + is_zoom_template = ZOOM_TEMPLATE_NAME in instance.template + + # Link (set 2) + should_render_link = whether_to_render_link(instance) + + # Zoom Effect + should_add_zoom_effect = is_zoom_template + should_wrap_image_for_zoom = ( + should_add_zoom_effect and + (has_figure_content or not should_render_link) + ) + should_add_zoom_class_to_link = ( + should_add_zoom_effect and + should_render_link and + not has_figure_content + ) + + # Attributes + should_add_attributes_to_image = ( + not has_figure_content and + not should_render_link + ) + + return { + 'should_render_link': should_render_link, + 'has_figure_content': has_figure_content, + 'should_wrap_image_for_zoom': should_wrap_image_for_zoom, + 'should_add_zoom_class_to_link': should_add_zoom_class_to_link, + 'should_add_attributes_to_image': should_add_attributes_to_image, + } + # djangocms_picture from djangocms_picture.cms_plugins import PicturePlugin as OriginalPicturePlugin @@ -70,6 +119,14 @@ class PicturePlugin(OriginalPicturePlugin): form = PicturePluginForm name = 'Image' + def render(self, context, instance, placeholder): + context = super().render(context, instance, placeholder) + + more_context = get_more_context_variables(instance) + context.update(more_context) + + return context + # To support generic Image plugin without uninstalling Bootstrap's # FAQ: Had been done cuz Image plugin had percieved use cases, # but is since not regularly used, but is used, thus maintained @@ -101,7 +158,13 @@ class Bootstrap4PicturePlugin(OriginalBootstrap4PicturePlugin): form = Bootstrap4PictureForm name = 'Picture / Image (Responsive)' + def render(self, context, instance, placeholder): + context = super().render(context, instance, placeholder) + + more_context = get_more_context_variables(instance) + context.update(more_context) + + return context + plugin_pool.unregister_plugin(OriginalBootstrap4PicturePlugin) plugin_pool.register_plugin(Bootstrap4PicturePlugin) - - logger.info("Extended PicturePlugin (and Bootstrap4PicturePlugin).") diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 41b59a56c..852854c10 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -579,10 +579,9 @@ def get_subdirs_as_module_names(path): ('center', _('Align center')), ] DJANGOCMS_PICTURE_TEMPLATES = [ - ('no_link_to_image', _('Do not link image to itself')), - ('no_link_to_ext_image', _('Do not link image to itself (DEPRECATED)')), + ('no_link_to_ext_image', _('Do not link to "External image"')), ('zoom_effect', _('Zoom image on hover')), - ('zoom_effect_no_link_to_image', _('Zoom image on hover & Do not link image to itself')), + ('zoom_effect_no_link_to_ext_image', _('Zoom image on hover & Do not link to "External image"')), ] # FILE UPLOAD VALUES MUST BE SET! diff --git a/taccsite_cms/templates/snippets/test/css-image-picture-block.html b/taccsite_cms/static/site_cms/css/test/djangocms-picture.css similarity index 94% rename from taccsite_cms/templates/snippets/test/css-image-picture-block.html rename to taccsite_cms/static/site_cms/css/test/djangocms-picture.css index 78e4b70df..0a91e3675 100644 --- a/taccsite_cms/templates/snippets/test/css-image-picture-block.html +++ b/taccsite_cms/static/site_cms/css/test/djangocms-picture.css @@ -1,5 +1,4 @@ - diff --git a/taccsite_cms/templates/djangocms_picture/default/picture.html b/taccsite_cms/templates/djangocms_picture/default/picture.html index ddcf3db2b..a62fd6e3f 100644 --- a/taccsite_cms/templates/djangocms_picture/default/picture.html +++ b/taccsite_cms/templates/djangocms_picture/default/picture.html @@ -1,42 +1,53 @@ {# https://github.com/django-cms/djangocms-picture/blob/3.0.0/djangocms_picture/templates/djangocms_picture/default/picture.html #} -{# TACC (mimic v3.0.0 to v4.0.0 changes): #} {# TACC (support children as caption content): #} +{# TACC (mimic v3.0.0 to v4.0.0 changes): #} +{# TACC (support image zoom): #} {# {% load thumbnail %} #} -{% load thumbnail l10n cms_tags %} +{% load thumbnail l10n cms_tags strip_class_attribute %} +{# /TACC #} {# /TACC #} {# /TACC #} -{# TACC (allow link to be conditional): #} -{% block picture_link_start %} +{# TACC (support custom condition): #} +{% if should_render_link %} {# /TACC #} -{% if picture_link %} - {# TACC (assign attributes to parent): #} - {% include "djangocms_picture/default/picture_link_start.html" %} + {# TACC (support image zoom): #} + {% if should_add_zoom_class_to_link %} + {% include "djangocms_picture/default/zoom_asset.html" %} + {% endif %} {# /TACC #} + {% endif %} -{# TACC (allow link to be conditional): #} -{% endblock %} -{# /TACC #} -{# TACC (allow figure to be overridden): #} -{% block picture_figure_start %} -{# /TACC #} + {# TACC (support children as caption content): #} -{# {% if instance.caption_text %} #} -{% if instance.caption_text or instance.child_plugin_instances %} +{% if has_figure_content %} +{# /TACC #} {# TACC (assign attributes to parent): #}
{# /TACC #} {% endif %} -{# /TACC #} -{# TACC (allow figure to be overridden): #} -{% endblock %} -{# /TACC #} -{# TACC (allow image wrapper): #} -{% block picture_wrap_start %} -{% endblock picture_wrap_start %} +{# TACC (support image zoom): #} +{% if should_wrap_image_for_zoom %} + {% include "djangocms_picture/default/zoom_asset.html" %} + +{% endif %} {# /TACC #} {# TACC (mimic v3.0.0 to v4.0.0 changes): #} {% localize off %} @@ -62,7 +73,7 @@ {# TACC (allow link to be conditional): #} {% block picture_attributes %} {# TACC (assign attributes to parent): #} - {% if not instance.caption_text and not picture_link and not instance.child_plugin_instances %} + {% if should_add_attributes_to_image %} {{ instance.attributes_str }} {% endif %} {# /TACC #} @@ -72,16 +83,15 @@ {# TACC (mimic v3.0.0 to v4.0.0 changes): #} {% endlocalize %} {# /TACC #} -{# TACC (allow_image_wrapper): #} -{% block picture_wrap_end %} -{% endblock picture_wrap_end %} +{# TACC (support image zoom): #} + {% if should_wrap_image_for_zoom %} + + {% endif %} {# /TACC #} -{# TACC (allow figure to be overridden): #} -{% block picture_figure_end %} +{# TACC (support custom condition): #} +{% if has_figure_content %} {# /TACC #} -{# {% if instance.caption_text %} #} -{% if instance.caption_text or instance.child_plugin_instances %} {# TACC (support children as caption content): #} {#
{{ instance.caption_text }}
#}
@@ -93,19 +103,12 @@ {# /TACC #}
{% endif %} -{# TACC (allow figure to be overridden): #} -{% endblock %} -{# /TACC #} -{# TACC (allow link to be conditional): #} -{% block picture_link_end %} +{# TACC (support custom condition): #} +{% if should_render_link %} {# /TACC #} -{% if picture_link %}
{% endif %} -{# TACC (allow link to be conditional): #} -{% endblock %} -{# /TACC #} {% comment %} # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img diff --git a/taccsite_cms/templates/djangocms_picture/default/picture_link_start.html b/taccsite_cms/templates/djangocms_picture/default/picture_link_start.html deleted file mode 100644 index fb2c5a0a4..000000000 --- a/taccsite_cms/templates/djangocms_picture/default/picture_link_start.html +++ /dev/null @@ -1,18 +0,0 @@ -{# https://github.com/django-cms/djangocms-picture/blob/3.0.0/djangocms_picture/templates/djangocms_picture/default/picture.html#L4-L6 #} - -{# @var className #} -{% load strip_class_attribute %} - - diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_asset.html b/taccsite_cms/templates/djangocms_picture/default/zoom_asset.html similarity index 100% rename from taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_asset.html rename to taccsite_cms/templates/djangocms_picture/default/zoom_asset.html diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html index 55b62f679..d9e697407 100644 --- a/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_ext_image/picture.html @@ -1,2 +1,6 @@ -{# backwards-compatibility for old name #} -{% extends "djangocms_picture/no_link_to_image/picture.html" %} +{% extends "djangocms_picture/default/picture.html" %} + +{# To allow "External image" to be rendered without a link #} +{# FAQ: Template exists to avoid adding a new model field #} +{# FAQ: Default template uses custom boolean context variables for logic #} +{# FAQ: App djangocms_picture assumes that an image, if not explicitely linked, must link to itself. But sometimes, we want an image to just be an image, unlinked. #} diff --git a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html index ad60a5d4c..5ab79b9f9 100644 --- a/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html +++ b/taccsite_cms/templates/djangocms_picture/no_link_to_image/picture.html @@ -1,24 +1,2 @@ -{% extends "djangocms_picture/default/picture.html" %} -{# To allow image to be rendered without a link #} -{# FAQ: App djangocms_picture assumes that an image, if not explicitely linked, must link to itself. But sometimes, we want an image to just be an image, unlinked. #} - -{# So picture is not wrapped in a link #} -{% block picture_link_start %} - {% if instance.link_url or instance.link_page_id %} - {% include "djangocms_picture/default/picture_link_start.html" %} - {% endif %} -{% endblock %} - -{# So picture attributes are added to unlinked picture #} -{% block picture_attributes %} - {% if not instance.caption_text and not instance.link_url and not instance.link_page_id and not instance.child_plugin_instances %} - {{ instance.attributes_str }} - {% endif %} -{% endblock %} - -{# So picture is not wrapped in a link #} -{% block picture_link_end %} - {% if instance.link_url or instance.link_page_id %} - - {% endif %} -{% endblock %} +{# backwards-compatibility for temporary name #} +{% extends "djangocms_picture/no_link_to_ext_image/picture.html" %} diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html b/taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html index 993517ec0..f1f398d5c 100644 --- a/taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html +++ b/taccsite_cms/templates/djangocms_picture/zoom_effect/picture.html @@ -1,24 +1,5 @@ {% extends "djangocms_picture/default/picture.html" %} -{# Add u-image-zoom class on link if link is present without figure #} -{% block picture_link_start %} - {% if picture_link and not instance.caption_text and not instance.child_plugin_instances %} - {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} - {% include "djangocms_picture/default/picture_link_start.html" with className="u-image-zoom--on-hover" %} - {% else %} - {{ block.super }} - {% endif %} -{% endblock %} - -{# Add u-image-zoom class on image wrapper if no link #} -{% block picture_wrap_start %} - {% if instance.caption_text or instance.child_plugin_instances or not picture_link %} - {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} - {% include "djangocms_picture/zoom_effect/zoom_wrapper_start.html" %} - {% endif %} -{% endblock %} -{% block picture_wrap_end %} - {% if instance.caption_text or instance.child_plugin_instances or not picture_link %} - {% include "djangocms_picture/zoom_effect/zoom_wrapper_end.html" %} - {% endif %} -{% endblock %} +{# To zoom image on hover #} +{# FAQ: Template exists to avoid adding a new model field #} +{# FAQ: Default template uses custom boolean context variables for logic #} diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html deleted file mode 100644 index 294567489..000000000 --- a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_end.html +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html b/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html deleted file mode 100644 index 7998a3d33..000000000 --- a/taccsite_cms/templates/djangocms_picture/zoom_effect/zoom_wrapper_start.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_ext_image/picture.html b/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_ext_image/picture.html new file mode 100644 index 000000000..e94d37638 --- /dev/null +++ b/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_ext_image/picture.html @@ -0,0 +1,5 @@ +{% extends "djangocms_picture/default/picture.html" %} + +{# To combine `zoom_effect` and `no_link_to_image` %} +{# SEE: taccsite_cms/templates/djangocms_picture/zoom_effect #} +{# SEE: taccsite_cms/templates/djangocms_picture/no_link_to_image #} diff --git a/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html b/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html deleted file mode 100644 index c882de1cf..000000000 --- a/taccsite_cms/templates/djangocms_picture/zoom_effect_no_link_to_image/picture.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "djangocms_picture/no_link_to_image/picture.html" %} - -{# Add u-image-zoom class on link if link is present without figure #} -{% block picture_link_start %} - {% if instance.link_url or instance.link_page_id %} - {% if not instance.caption_text and not instance.child_plugin_instances %} - {% include "djangocms_picture/default/picture_link_start.html" with className="u-image-zoom--on-hover" %} - {% else %} - {{ block.super }} - {% endif %} - {% else %} - {{ block.super }} - {% endif %} -{% endblock %} - -{# Add u-image-zoom class on image wrapper if no link and no figure #} -{% block picture_wrap_start %} - {% if instance.caption_text or instance.child_plugin_instances %} - {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} - {% include "djangocms_picture/zoom_effect/zoom_wrapper_start.html" %} - {% elif not instance.link_url and not instance.link_page_id %} - {% include "djangocms_picture/zoom_effect/zoom_asset.html" %} - {% include "djangocms_picture/zoom_effect/zoom_wrapper_start.html" %} - {% endif %} -{% endblock %} -{% block picture_wrap_end %} - {% if instance.caption_text or instance.child_plugin_instances or not instance.link_url and not instance.link_page_id %} - {% include "djangocms_picture/zoom_effect/zoom_wrapper_end.html" %} - {% endif %} -{% endblock %} From 478ffb5ee6f501192141a00ebe9ca2d7488849b2 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 25 Jul 2025 20:53:41 -0500 Subject: [PATCH 10/60] chore(README): new line (to get new main commit) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ad87d3e02..2e4eadb85 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,7 @@ To contribute, first read [How to Contirbute][Contributing]. | `python manage.py collectstatic` | [django](https://docs.djangoproject.com/en/3.2/howto/static-files/) | `python manage.py createsuperuser` | [django cms](https://docs.django-cms.org/en/release-3.8.x/how_to/install.html#admin-user), [django](https://docs.djangoproject.com/en/3.2/ref/django-admin/#createsuperuser) + [Camino]: https://github.com/TACC/Camino From df14ad6e76fe344ee263eb05e00435f7aa05fa8b Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 28 Jul 2025 11:00:32 -0500 Subject: [PATCH 11/60] refactor: u-image-zoom via core-styles (#970) * deps: core-styles v2.46.1 * refactor: u-image-zoom via core-styles --- package-lock.json | 14 +++++++------- package.json | 2 +- .../djangocms_picture/default/picture.html | 6 ------ .../djangocms_picture/default/zoom_asset.html | 7 ------- 4 files changed, 8 insertions(+), 21 deletions(-) delete mode 100644 taccsite_cms/templates/djangocms_picture/default/zoom_asset.html diff --git a/package-lock.json b/package-lock.json index a0472cd77..776bd2ca7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "minimist": "^1.2.6" }, "devDependencies": { - "@tacc/core-styles": "^2.45.0" + "@tacc/core-styles": "^2.46.1" }, "engines": { "node": ">=16", @@ -1132,9 +1132,9 @@ } }, "node_modules/@tacc/core-styles": { - "version": "2.45.0", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.45.0.tgz", - "integrity": "sha512-ujck0rgUFb+vo42Qr5MRUfF8KHnIAEjHsRuh9dhBaeo6mrRhyjBCq+JgGryjQxOiCnFFM8yuYrJlUPsCaSEGCA==", + "version": "2.46.1", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.1.tgz", + "integrity": "sha512-ln6ihKWtMTwDxQKmBL1H/2P2+mLut1h2n/KziKUlpQ7+PEaBFHaC1XFE8FuROmX+H/aZnpCW8xXALIcUQcErnw==", "dev": true, "license": "MIT", "bin": { @@ -4733,9 +4733,9 @@ } }, "@tacc/core-styles": { - "version": "2.45.0", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.45.0.tgz", - "integrity": "sha512-ujck0rgUFb+vo42Qr5MRUfF8KHnIAEjHsRuh9dhBaeo6mrRhyjBCq+JgGryjQxOiCnFFM8yuYrJlUPsCaSEGCA==", + "version": "2.46.1", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.1.tgz", + "integrity": "sha512-ln6ihKWtMTwDxQKmBL1H/2P2+mLut1h2n/KziKUlpQ7+PEaBFHaC1XFE8FuROmX+H/aZnpCW8xXALIcUQcErnw==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index efa0c1242..0471f33b1 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,6 @@ }, "homepage": "https://github.com/TACC/Core-CMS", "devDependencies": { - "@tacc/core-styles": "^2.45.0" + "@tacc/core-styles": "^2.46.1" } } diff --git a/taccsite_cms/templates/djangocms_picture/default/picture.html b/taccsite_cms/templates/djangocms_picture/default/picture.html index a62fd6e3f..463006bb3 100644 --- a/taccsite_cms/templates/djangocms_picture/default/picture.html +++ b/taccsite_cms/templates/djangocms_picture/default/picture.html @@ -11,11 +11,6 @@ {# TACC (support custom condition): #} {% if should_render_link %} {# /TACC #} - {# TACC (support image zoom): #} - {% if should_add_zoom_class_to_link %} - {% include "djangocms_picture/default/zoom_asset.html" %} - {% endif %} - {# /TACC #} {% endif %} {# /TACC #} diff --git a/taccsite_cms/templates/djangocms_picture/default/zoom_asset.html b/taccsite_cms/templates/djangocms_picture/default/zoom_asset.html deleted file mode 100644 index 230e3e264..000000000 --- a/taccsite_cms/templates/djangocms_picture/default/zoom_asset.html +++ /dev/null @@ -1,7 +0,0 @@ -{% load sekizai_tags %} - -{% addtoblock "css" %} - -{% endaddtoblock %} From 461ca3eda67471a0255d1f19ae4a1aead1cca37f Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 28 Jul 2025 11:25:49 -0500 Subject: [PATCH 12/60] chore: v4.36.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7a00eb064..7622670a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "4.35.0" +version = "4.36.0" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 34acc585a57fe3a9efb3d2ac6591be8b200e973e Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 28 Jul 2025 13:27:41 -0500 Subject: [PATCH 13/60] fix: u-image-zoom validation (#971) --- taccsite_cms/djangocms_picture/extend.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/taccsite_cms/djangocms_picture/extend.py b/taccsite_cms/djangocms_picture/extend.py index 2d2292b38..52ce32bb5 100644 --- a/taccsite_cms/djangocms_picture/extend.py +++ b/taccsite_cms/djangocms_picture/extend.py @@ -40,7 +40,7 @@ def validate_zoom_template(instance): would_render_link = whether_to_render_link(instance) should_add_zoom_effect = ZOOM_TEMPLATE_NAME in instance.template parent_plugin = instance.parent.get_plugin_instance()[0] if instance.parent else None - is_in_link = isinstance(parent_plugin, LinkPlugin) if parent_plugin else False + is_in_link = instance.parent.plugin_type == 'LinkPlugin' if instance.parent else False if (should_add_zoom_effect and not would_render_link and not is_in_link): errors['template'] = ZOOM_TEMPLATE_ERROR @@ -53,12 +53,6 @@ def get_more_context_variables(instance): Calculate boolean context variables to simplify template logic. Returns a dictionary of context variables. """ - # Link (set 1) - has_explicit_link = bool(instance.get_link()) - parent_plugin = instance.parent.get_plugin_instance()[0] if instance.parent else None - is_in_link_plugin = isinstance(parent_plugin, LinkPlugin) if parent_plugin else False - has_any_link = has_explicit_link or is_in_link_plugin - # Figure/Caption has_caption_text = bool(instance.caption_text) has_child_plugins = bool(instance.child_plugin_instances) @@ -67,7 +61,7 @@ def get_more_context_variables(instance): # Template is_zoom_template = ZOOM_TEMPLATE_NAME in instance.template - # Link (set 2) + # Link should_render_link = whether_to_render_link(instance) # Zoom Effect From b2993c0e10479238b8902702a0ed59a4706d8495 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 28 Jul 2025 15:13:28 -0500 Subject: [PATCH 14/60] fix: space under span.u-image-zoom img (#972) * fix: space under span.u-image-zoom img * deps: core-styles v2.46.2 --- package-lock.json | 14 +++++++------- package.json | 2 +- .../components/django.cms.blog.app.page.css | 9 +++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 776bd2ca7..276eaf0c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "minimist": "^1.2.6" }, "devDependencies": { - "@tacc/core-styles": "^2.46.1" + "@tacc/core-styles": "^2.46.2" }, "engines": { "node": ">=16", @@ -1132,9 +1132,9 @@ } }, "node_modules/@tacc/core-styles": { - "version": "2.46.1", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.1.tgz", - "integrity": "sha512-ln6ihKWtMTwDxQKmBL1H/2P2+mLut1h2n/KziKUlpQ7+PEaBFHaC1XFE8FuROmX+H/aZnpCW8xXALIcUQcErnw==", + "version": "2.46.2", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.2.tgz", + "integrity": "sha512-b3MTccuLswbJM19ysX85vHYt6l/hHtvEgR3ZhKZZvoVXPBZjyfhl9zvnOrnQPB5tnLMt59nKdyHo+XcEj67lgA==", "dev": true, "license": "MIT", "bin": { @@ -4733,9 +4733,9 @@ } }, "@tacc/core-styles": { - "version": "2.46.1", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.1.tgz", - "integrity": "sha512-ln6ihKWtMTwDxQKmBL1H/2P2+mLut1h2n/KziKUlpQ7+PEaBFHaC1XFE8FuROmX+H/aZnpCW8xXALIcUQcErnw==", + "version": "2.46.2", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.2.tgz", + "integrity": "sha512-b3MTccuLswbJM19ysX85vHYt6l/hHtvEgR3ZhKZZvoVXPBZjyfhl9zvnOrnQPB5tnLMt59nKdyHo+XcEj67lgA==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 0471f33b1..23b32a020 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,6 @@ }, "homepage": "https://github.com/TACC/Core-CMS", "devDependencies": { - "@tacc/core-styles": "^2.46.1" + "@tacc/core-styles": "^2.46.2" } } diff --git a/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.page.css b/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.page.css index 4a6c5ef4f..13dadc8da 100644 --- a/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.page.css +++ b/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.page.css @@ -170,6 +170,15 @@ Styleguide Components.DjangoCMS.Blog.App.Page margin-inline: auto; } +/* To add space under aligned images */ +/* NOTE: All images should be aligned by news editor, + so missing space is considered news editor error */ +:--article-page .blog-content .align-right, +:--article-page .blog-content .align-center, +:--article-page .blog-content .align-left { + margin-bottom: var(--global-space--grid-gap); +} + /* To always align Bootstrap blockquote text left */ /* FAQ: Boostrap, loaded in foundation layer, used !important */ /* TODO: When extending Core-Styles c-news, .blockquote... is only for CMS */ From 86f76fbc1e3cc3da7685a297a4da49dffa279013 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 28 Jul 2025 15:26:34 -0500 Subject: [PATCH 15/60] fix: v4.36.1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7622670a4..fcd8acad2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "4.36.0" +version = "4.36.1" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 9d80485d83182b0a23ebce64d6ad0b1f81bc70d9 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:04:55 -0500 Subject: [PATCH 16/60] feat: snippet template to redirect external article (#973) * feat: snippet to redirect external article * fix: load Core-CMS script not tup-ui script --- .../snippets/news/open-external-articles.html | 2 +- .../news/redirect-external-article.html | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 taccsite_cms/templates/snippets/news/redirect-external-article.html diff --git a/taccsite_cms/templates/snippets/news/open-external-articles.html b/taccsite_cms/templates/snippets/news/open-external-articles.html index 99dbafa6d..ca383e8eb 100644 --- a/taccsite_cms/templates/snippets/news/open-external-articles.html +++ b/taccsite_cms/templates/snippets/news/open-external-articles.html @@ -1,7 +1,7 @@ {# To open external news article, instead of internal news article #} {% load static %} - From 6913b383e6a0d78efebad76a5913509b5402c9d2 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 29 Jul 2025 14:10:59 -0500 Subject: [PATCH 17/60] chore: v4.36.2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fcd8acad2..1e23b1301 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "4.36.1" +version = "4.36.2" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 04a54de5d1890a84e2aeaeeeaac8eda3cacf09ff Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 4 Aug 2025 15:42:36 -0500 Subject: [PATCH 18/60] deps: djangocms-bootstrap4 v3 (#974) --- poetry.lock | 16 ++++++---------- pyproject.toml | 4 +--- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4fd2870f6..9d86b1964 100644 --- a/poetry.lock +++ b/poetry.lock @@ -747,13 +747,15 @@ taggit-helpers = ["django-taggit-helpers"] [[package]] name = "djangocms-bootstrap4" -version = "3.0.1" +version = "3.0.2" description = "Adds Bootstrap 4 components as plugins." optional = false python-versions = "*" groups = ["main"] -files = [] -develop = false +files = [ + {file = "djangocms_bootstrap4-3.0.2-py3-none-any.whl", hash = "sha256:3b7e7eb1b7551cf433bf2bb0f3601d47645203c3bb4ad75ec097eb4bd81a34cf"}, + {file = "djangocms_bootstrap4-3.0.2.tar.gz", hash = "sha256:e931aefadbd22ab00e6cea8b7224da767afea125df15bf0c8a8d5f7872153e64"}, +] [package.dependencies] django-cms = ">=3.7,<4" @@ -767,12 +769,6 @@ djangocms-text-ckeditor = ">=3.1.0" [package.extras] static-ace = ["djangocms-static-ace"] -[package.source] -type = "git" -url = "https://github.com/django-cms/djangocms-bootstrap4.git" -reference = "49983f4" -resolved_reference = "49983f4175ec4a4e2b5076993a893cbdd79c4ab2" - [[package]] name = "djangocms-column" version = "2.0.0" @@ -2502,4 +2498,4 @@ testing = ["func-timeout", "jaraco.itertools"] [metadata] lock-version = "2.1" python-versions = ">=3.11,<4.0" -content-hash = "077910c85e2fda3f3ff38d22d4275d876d2ecef54cd3e21ed2ee744c56771495" +content-hash = "8ef7c041a1522e5e00995677cce04b851ebfd5852399795d29aa902b49526d21" diff --git a/pyproject.toml b/pyproject.toml index 1e23b1301..71f7daf35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,9 +45,7 @@ djangocms-admin-style = "~3.2.6" djangocms-apphook-setup = "0.4.1" djangocms-attributes-field = "2.1.0" djangocms-blog = "^1.2" -# TO get a commit in main (since v3.0.1) to fix Container error -# https://github.com/django-cms/djangocms-bootstrap4/pull/164 -djangocms-bootstrap4 = {git = "https://github.com/django-cms/djangocms-bootstrap4.git", rev = "49983f4"} +djangocms-bootstrap4 = "^3.0" djangocms-column = "^2.0" djangocms-file = "3.0.0" djangocms-forms-maintained = { git = "https://github.com/TACC/djangocms-forms", rev = "6b59ff366495915f06f4d6fac01a2f0aa9efecaf" } From ab22440dbe2bd2687dbe675063aa575bd377d76d Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 4 Aug 2025 17:53:49 -0500 Subject: [PATCH 19/60] chore: move imports to function that uses them --- taccsite_cms/djangocms_picture/extend.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/taccsite_cms/djangocms_picture/extend.py b/taccsite_cms/djangocms_picture/extend.py index 52ce32bb5..21798b481 100644 --- a/taccsite_cms/djangocms_picture/extend.py +++ b/taccsite_cms/djangocms_picture/extend.py @@ -1,11 +1,8 @@ def extendPicturePlugin(): - from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from cms.plugin_pool import plugin_pool - from djangocms_link.cms_plugins import LinkPlugin - ZOOM_TEMPLATE_NAME = 'zoom_effect' ZOOM_TEMPLATE_LABEL = 'Zoom image on hover' ZOOM_TEMPLATE_NOTE = _('The "%(zoom_template_label)s" templates only have effect if Image either has a Link or is within a Link.') % {"zoom_template_label": ZOOM_TEMPLATE_LABEL} @@ -34,6 +31,8 @@ def whether_to_render_link(instance): def validate_zoom_template(instance): """Validates: 'Template' field choice 'Zoom image …'""" + from django.core.exceptions import ValidationError + from djangocms_link.cms_plugins import LinkPlugin errors = {} From 4b724369ea0f8b7967ce5bc819f60f660daa4e1e Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 5 Aug 2025 16:16:31 -0500 Subject: [PATCH 20/60] feat: let custom sites overwrite app templates (#975) --- taccsite_cms/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 852854c10..1c7340c53 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -349,8 +349,10 @@ def gettext(s): return s # FAQ: List custom directory first, so custom templates take precedence # SEE: https://docs.djangoproject.com/en/2.2/topics/templates/#configuration 'DIRS': glob( + # XXX: Strange and from my ignorant implementation os.path.join(BASE_DIR, 'taccsite_custom') ) + [ + os.path.join(BASE_DIR, 'taccsite_custom', 'templates'), os.path.join(BASE_DIR, 'taccsite_cms', 'templates') ], 'OPTIONS': { From 69dcb55836c43bb407706b570ffc35bdf1fd9429 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 15 Aug 2025 10:39:53 -0500 Subject: [PATCH 21/60] chore: v4.36.3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 71f7daf35..a686634eb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "4.36.2" +version = "4.36.3" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 4a457ca65ac2024af360016be0171f5ecf6cf84f Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 4 Sep 2025 10:06:52 -0700 Subject: [PATCH 22/60] feat: new custom django command for devs (#728) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: command, find plugins within TextPlugin ⚠️ ⚠️ INCOMPLETE. DOES NOT WORK. SEE `get_parent_text_plugins`. * feat: command, find pages with given plugin ⚠️ ⚠️ UNTESTED & UNPOLISHED AS DJANGO COMMAND. * fix: find_pages_with_plugins tested on Texascale prod ad-hoc by copy/pasting and asking AI for help * chore: delete unused unfinished plugin * doc: find_pages_with_plugins * refactor: rename command --- taccsite_cms/management/commands/README.md | 16 ++++++++++++ .../management/commands/list_plugin_pages.py | 25 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 taccsite_cms/management/commands/list_plugin_pages.py diff --git a/taccsite_cms/management/commands/README.md b/taccsite_cms/management/commands/README.md index d2416238d..e28094462 100644 --- a/taccsite_cms/management/commands/README.md +++ b/taccsite_cms/management/commands/README.md @@ -2,6 +2,7 @@ - [How to Use](#how-to-use) - [List Pages Using Each Template](#list-pages-using-each-template) +- [List Pages Using Plugins](#list-pages-using-plugins) - [Set Groups & Permissions](#set-groups--permissions) - [Reference](#reference) @@ -25,6 +26,21 @@ Usage: python manage.py list_page_templates ``` +## List Pages Using Plugins + +This command lists all pages that use a specific plugin instance (given a plugin instance ID), along with the page's path. + +Usage: +```sh +python manage.py list_plugin_pages [ ...] +``` + +Example: +```sh +python manage.py list_plugin_pages 42 99 +``` + + ## Set Groups & Permissions Every file in [`group_perms/`](./group_perms) represents a group. Each group's intended usage is described at the top of its file. Permissions are set via function calls in each file.[^1] diff --git a/taccsite_cms/management/commands/list_plugin_pages.py b/taccsite_cms/management/commands/list_plugin_pages.py new file mode 100644 index 000000000..8ae1b244d --- /dev/null +++ b/taccsite_cms/management/commands/list_plugin_pages.py @@ -0,0 +1,25 @@ +from django.core.management import BaseCommand +from django.apps import apps + +class Command(BaseCommand): + help = 'Finds the page that uses a specific plugin instance by its ID' + + def add_arguments(self, parser): + parser.add_argument('plugin_instance_ids', nargs='+', type=str) + + def handle(self, *args, **options): + for plugin_instance_id in options['plugin_instance_ids']: + page = self.find_page_using_plugin_instance(plugin_instance_id) + if page: + self.stdout.write(f'Plugin instance ID {plugin_instance_id} is used on page: {page.get_path()}') + else: + self.stdout.write(f'No page found using plugin instance ID {plugin_instance_id}') + + def find_page_using_plugin_instance(self, plugin_instance_id): + try: + CMSPlugin = apps.get_model('cms', 'CMSPlugin') + plugin_instance = CMSPlugin.objects.get(id=plugin_instance_id) + page = plugin_instance.placeholder.page if plugin_instance.placeholder else None + return page + except CMSPlugin.DoesNotExist: + return None From 6661622aa1861a2cdf331acbbc099fe297d69e7f Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:46:11 -0500 Subject: [PATCH 23/60] docs: we do not use Core-CMS-Resources --- taccsite_custom/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taccsite_custom/README.md b/taccsite_custom/README.md index 0e7464193..df4ae0d5f 100644 --- a/taccsite_custom/README.md +++ b/taccsite_custom/README.md @@ -9,4 +9,4 @@ A functional placeholder directory into which the original remaining custom inst — add unique files and functionality. This directory has special logic and support in `settings.py`. > [!NOTE] -> This directory is a vestige of archived [Core CMS Resources](https://github.com/TACC/Core-CMS-Resources/tree/151ef91f) and we may re-evaluate whether to continue to use it. +> This directory is a vestige of archived [Core CMS Resources](https://github.com/TACC/Core-CMS-Resources/tree/151ef91f). From bfcca6ab66231e2f1bcdf4df97e59b333df2761b Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 8 Sep 2025 17:22:10 -0500 Subject: [PATCH 24/60] feat: let client have fullwidth breadcrumbs (#985) --- taccsite_cms/templates/fullwidth.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/taccsite_cms/templates/fullwidth.html b/taccsite_cms/templates/fullwidth.html index 98dab9413..13167975b 100755 --- a/taccsite_cms/templates/fullwidth.html +++ b/taccsite_cms/templates/fullwidth.html @@ -1,8 +1,9 @@ {% extends "base.html" %} {% load cms_tags %} -{# To remove container and breadcrumbs #} +{# To remove container and not render breadcrumbs #} {% block content %} + {% block breadcrumbs %}{% endblock breadcrumbs %} {% block cms_content %} {% placeholder "content" %} {% endblock cms_content %} From 8904111e77602feac822b5596084b8c2898b33e8 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 8 Sep 2025 17:51:35 -0500 Subject: [PATCH 25/60] docs: revise note about code from 3rd-party --- taccsite_cms/templates/cms_menu.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taccsite_cms/templates/cms_menu.html b/taccsite_cms/templates/cms_menu.html index bcd6b1e4d..0d67909c8 100644 --- a/taccsite_cms/templates/cms_menu.html +++ b/taccsite_cms/templates/cms_menu.html @@ -1,6 +1,6 @@ {% load menu_tags tacc_uri_shortcuts limit_visibility_in_menu %} -{# NOTE: This template content is copied from a third-party plugin that we do not use nor need #} +{# NOTE: This template content was copied (and changed) from 3rd-party plugin that we have long since not used #} {# SEE: https://github.com/jrief/djangocms-bootstrap/blob/aa74994/cms_bootstrap/templates/bootstrap4/menu/navbar.html #} {% spaceless %} From 723c1829c8d677bc07441003675d259826e78606 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 8 Sep 2025 18:09:35 -0500 Subject: [PATCH 26/60] fix: client cannot change breadcrumb inclusion on guides (#986) --- taccsite_cms/templates/guide.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/taccsite_cms/templates/guide.html b/taccsite_cms/templates/guide.html index 72ec294d7..f2f68123d 100644 --- a/taccsite_cms/templates/guide.html +++ b/taccsite_cms/templates/guide.html @@ -13,7 +13,9 @@ {% block content %}
- {% include "nav_cms_breadcrumbs.html" %} + {% block breadcrumbs %} + {% include "nav_cms_breadcrumbs.html" %} + {% endblock breadcrumbs %} {% block guide %} {% placeholder "content" %} {% endblock guide %} From 9d1cff2163f54056d6f47c75da227b562f05b344 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 12 Sep 2025 10:49:01 -0700 Subject: [PATCH 27/60] fix: do not allow accidental blog install (#987) --- taccsite_cms/settings_custom.example.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/taccsite_cms/settings_custom.example.py b/taccsite_cms/settings_custom.example.py index c30612115..9b00ae078 100644 --- a/taccsite_cms/settings_custom.example.py +++ b/taccsite_cms/settings_custom.example.py @@ -100,16 +100,16 @@ # DJANGOCMS_BLOG ######################## -BLOG_AUTO_SETUP = True # Set to False after setup (minimize overhead) -BLOG_AUTO_HOME_TITLE ='Home' -BLOG_AUTO_BLOG_TITLE = 'News' -BLOG_AUTO_APP_TITLE = 'News' -BLOG_AUTO_NAMESPACE = 'News' -BLOG_ENABLE_COMMENTS = False +# BLOG_AUTO_SETUP = True # Set to False after setup (minimize overhead) +# BLOG_AUTO_HOME_TITLE ='Home' +# BLOG_AUTO_BLOG_TITLE = 'News' +# BLOG_AUTO_APP_TITLE = 'News' +# BLOG_AUTO_NAMESPACE = 'News' +# BLOG_ENABLE_COMMENTS = False ######################## # DJANGOCMS_BLOG: TACC ######################## -PORTAL_BLOG_SHOW_CATEGORIES = True -PORTAL_BLOG_SHOW_TAGS = True +# PORTAL_BLOG_SHOW_CATEGORIES = True +# PORTAL_BLOG_SHOW_TAGS = True From 2c6896a5d96795a0bb469b6c8008e3a2c10081f7 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 12 Sep 2025 17:46:56 -0700 Subject: [PATCH 28/60] feat: progressive web app & full favicon (#988) (#989) --- taccsite_cms/settings.py | 10 +++++++++ taccsite_cms/settings_custom.example.py | 11 +++++++++ .../site_cms/favicon/apple-touch-icon.png | Bin 0 -> 20363 bytes .../static/site_cms/favicon/favicon-96x96.png | Bin 0 -> 8263 bytes .../static/site_cms/favicon/favicon.ico | Bin 0 -> 15086 bytes .../static/site_cms/favicon/favicon.svg | 3 +++ .../static/site_cms/favicon/site.webmanifest | 21 ++++++++++++++++++ .../favicon/web-app-manifest-192x192.png | Bin 0 -> 22148 bytes .../favicon/web-app-manifest-512x512.png | Bin 0 -> 92938 bytes .../static/site_cms/img/favicons/favicon.ico | Bin 34494 -> 0 bytes taccsite_cms/templates/assets_custom.html | 10 ++++++--- 11 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 taccsite_cms/static/site_cms/favicon/apple-touch-icon.png create mode 100644 taccsite_cms/static/site_cms/favicon/favicon-96x96.png create mode 100644 taccsite_cms/static/site_cms/favicon/favicon.ico create mode 100644 taccsite_cms/static/site_cms/favicon/favicon.svg create mode 100644 taccsite_cms/static/site_cms/favicon/site.webmanifest create mode 100644 taccsite_cms/static/site_cms/favicon/web-app-manifest-192x192.png create mode 100644 taccsite_cms/static/site_cms/favicon/web-app-manifest-512x512.png delete mode 100644 taccsite_cms/static/site_cms/img/favicons/favicon.ico diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 1c7340c53..ace157a47 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -262,6 +262,15 @@ def gettext(s): return s "is_remote": False, "img_file_src": "site_cms/img/favicons/favicon.ico", } +favicon_path = f"/static/site_cms/favicon/" +PORTAL_FAVICON_HTML = f''' + + + + + + +''' ######################## @@ -864,6 +873,7 @@ def get_subdirs_as_module_names(path): 'PORTAL_BRANDING', 'PORTAL_LOGO', 'PORTAL_FAVICON', + 'PORTAL_FAVICON_HTML', 'PORTAL_IS_TACC_CORE_PORTAL', 'PORTAL_HAS_LOGIN', 'PORTAL_HAS_SEARCH', diff --git a/taccsite_cms/settings_custom.example.py b/taccsite_cms/settings_custom.example.py index 9b00ae078..0c41f1b7b 100644 --- a/taccsite_cms/settings_custom.example.py +++ b/taccsite_cms/settings_custom.example.py @@ -85,6 +85,17 @@ "is_remote": True, "img_file_src": "https://cdn.jsdelivr.net/gh/TACC/Core-CMS@v4.33.0/taccsite_cms/static/site_cms/img/favicons/favicon.ico", } +# The PORTAL_FAVICON_HTML takes precedence over PORTAL_FAVICON, +# This HTML is like output from https://realfavicongenerator.net/ circa 2025-09 +# favicon_path = "https://cdn.jsdelivr.net/gh/TACC/Core-CMS-Custom@________/________/favicon/" +# PORTAL_FAVICON_HTML = f''' +# +# +# +# +# +# +# ''' ######################## # SEARCH diff --git a/taccsite_cms/static/site_cms/favicon/apple-touch-icon.png b/taccsite_cms/static/site_cms/favicon/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0697cb2d0bdaffa40cea09713a4400cfebbec45a GIT binary patch literal 20363 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 PSu3;y+jI7}KBWE!vB*ck literal 0 HcmV?d00001 diff --git a/taccsite_cms/static/site_cms/favicon/favicon.svg b/taccsite_cms/static/site_cms/favicon/favicon.svg new file mode 100644 index 000000000..d5550f7dc --- /dev/null +++ b/taccsite_cms/static/site_cms/favicon/favicon.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/taccsite_cms/static/site_cms/favicon/site.webmanifest b/taccsite_cms/static/site_cms/favicon/site.webmanifest new file mode 100644 index 000000000..913ac9706 --- /dev/null +++ b/taccsite_cms/static/site_cms/favicon/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "Texas Advanced Computing Center", + "short_name": "TACC", + "icons": [ + { + "src": "/site_cms/favicon/web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/site_cms/favicon/web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/taccsite_cms/static/site_cms/favicon/web-app-manifest-192x192.png b/taccsite_cms/static/site_cms/favicon/web-app-manifest-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..3ca5458ed5a264f1f850f3219930764a53072c00 GIT binary patch literal 22148 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 W4Dx@^7z1z5SmxsaPGA3z5%^ys-eMU5 diff --git a/taccsite_cms/templates/assets_custom.html b/taccsite_cms/templates/assets_custom.html index 60ecefb61..45d57cf73 100644 --- a/taccsite_cms/templates/assets_custom.html +++ b/taccsite_cms/templates/assets_custom.html @@ -8,9 +8,13 @@ {% endcomment %} -{% with settings.PORTAL_FAVICON as favicon %} - -{% endwith %} +{% if settings.PORTAL_FAVICON_HTML %} + {{ settings.PORTAL_FAVICON_HTML|safe }} +{% else %} + {% with settings.PORTAL_FAVICON as favicon %} + + {% endwith %} +{% endif %} {% with settings.PORTAL_STYLES as styles %} From 5136026675241b5f318ab6a2851d095df22e5d60 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 30 Sep 2025 15:45:29 -0700 Subject: [PATCH 29/60] feat: PORTAL_LOGIN_PATH (#990) (#991) --- taccsite_cms/settings.py | 2 ++ taccsite_cms/templates/nav_portal.html | 11 ++++++++--- taccsite_cms/templates/nav_portal.raw.html | 13 ++++++++++--- taccsite_cms/urls.py | 8 +------- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index ace157a47..d5f200937 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -280,6 +280,7 @@ def gettext(s): return s PORTAL_IS_TACC_CORE_PORTAL = True PORTAL_HAS_LOGIN = True PORTAL_HAS_SEARCH = True +PORTAL_LOGIN_PATH = '/login' # Only use one of these values: 'sm', 'md', 'lg', 'xl' # SEE: https://getbootstrap.com/docs/4.0/components/navbar/#responsive-behaviors @@ -876,6 +877,7 @@ def get_subdirs_as_module_names(path): 'PORTAL_FAVICON_HTML', 'PORTAL_IS_TACC_CORE_PORTAL', 'PORTAL_HAS_LOGIN', + 'PORTAL_LOGIN_PATH', 'PORTAL_HAS_SEARCH', 'PORTAL_NAV_WIDTH', 'PORTAL_STYLES', diff --git a/taccsite_cms/templates/nav_portal.html b/taccsite_cms/templates/nav_portal.html index 8e1748ffb..a51129ecb 100644 --- a/taccsite_cms/templates/nav_portal.html +++ b/taccsite_cms/templates/nav_portal.html @@ -1,13 +1,17 @@ -{# @var className #} +{# @var className, settings #} {# WARNING: Some markup is duplicated in other repositories #} {# SEE: https://confluence.tacc.utexas.edu/x/LoCnCQ #}
    - - {# FAQ: Content populated via JavaScript, below #} + {# This content can be replaced by JavaScript below #} + {% if settings.PORTAL_HAS_LOGIN and not settings.PORTAL_IS_TACC_CORE_PORTAL %} + {% include "./nav_portal.raw.html" %} + {% endif %}
+ +{% if settings.PORTAL_IS_TACC_CORE_PORTAL %} +{% endif %} diff --git a/taccsite_cms/templates/nav_portal.raw.html b/taccsite_cms/templates/nav_portal.raw.html index 41dc44ea0..cbd778806 100644 --- a/taccsite_cms/templates/nav_portal.raw.html +++ b/taccsite_cms/templates/nav_portal.raw.html @@ -1,3 +1,10 @@ -{# intentionally empty #} - +{# @var settings #} + + + +
diff --git a/taccsite_cms/urls.py b/taccsite_cms/urls.py index 8980625f7..fc9de2261 100755 --- a/taccsite_cms/urls.py +++ b/taccsite_cms/urls.py @@ -31,7 +31,7 @@ if getattr(settings, 'PORTAL_IS_TACC_CORE_PORTAL', True): urlpatterns += [ - # To allow direct access to markup for Portal and User Guide to render + # To allow direct access to markup for Portal to render url(r'^cms/nav/search/markup/$', TemplateView.as_view(template_name='nav_search.raw.html'), name='search_bar_markup'), url(r'^cms/nav/pages/markup/$', TemplateView.as_view(template_name='nav_cms.raw.html'), name='menu_pages_markup'), url(r'^cms/header/branding/markup/$', TemplateView.as_view(template_name='header_branding.html'), name='header_branding_markup'), @@ -49,12 +49,6 @@ except ModuleNotFoundError: pass -if getattr(settings, 'PORTAL_HAS_LOGIN', True): - urlpatterns += [ - # To provide markup when Portal is missing - url(r'^core/markup/nav/$', TemplateView.as_view(template_name='nav_portal.raw.html'), name='portal_nav_markup'), - ] - urlpatterns += [ # The Django CMS urls url(r'^', include('cms.urls')), From 14611bfe624cd69e841d00e37a92333a2ebe8609 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:29:08 -0500 Subject: [PATCH 30/60] chore: v4.36.4 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a686634eb..ed559c617 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "4.36.3" +version = "4.36.4" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 8494266f41d4438e0a9e9baee2931ff8daebe3b1 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Wed, 1 Oct 2025 12:30:29 -0700 Subject: [PATCH 31/60] fix: big error if core portal expected but absent (#993) (#994) --- taccsite_cms/templates/nav_portal.html | 2 -- taccsite_cms/templates/nav_portal.raw.html | 4 ++++ taccsite_cms/urls.py | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/taccsite_cms/templates/nav_portal.html b/taccsite_cms/templates/nav_portal.html index a51129ecb..2c05f85d5 100644 --- a/taccsite_cms/templates/nav_portal.html +++ b/taccsite_cms/templates/nav_portal.html @@ -5,9 +5,7 @@
    {# This content can be replaced by JavaScript below #} - {% if settings.PORTAL_HAS_LOGIN and not settings.PORTAL_IS_TACC_CORE_PORTAL %} {% include "./nav_portal.raw.html" %} - {% endif %}
diff --git a/taccsite_cms/templates/nav_portal.raw.html b/taccsite_cms/templates/nav_portal.raw.html index cbd778806..4aa567ea5 100644 --- a/taccsite_cms/templates/nav_portal.raw.html +++ b/taccsite_cms/templates/nav_portal.raw.html @@ -3,8 +3,12 @@ +{% if settings.PORTAL_IS_TACC_CORE_PORTAL %} + +{% else %} +{% endif %} diff --git a/taccsite_cms/urls.py b/taccsite_cms/urls.py index fc9de2261..ea475b3be 100755 --- a/taccsite_cms/urls.py +++ b/taccsite_cms/urls.py @@ -49,6 +49,12 @@ except ModuleNotFoundError: pass +if getattr(settings, 'PORTAL_IS_TACC_CORE_PORTAL', True): + urlpatterns += [ + # To provide markup if TACC/Core-Portal is missing + url(r'^core/markup/nav/$', TemplateView.as_view(template_name='nav_portal.raw.html'), name='portal_nav_markup'), + ] + urlpatterns += [ # The Django CMS urls url(r'^', include('cms.urls')), From f8a59caaefe7efd1fedcd68d2478828009a9797b Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:35:41 -0500 Subject: [PATCH 32/60] docs: move docs/contributing to CONTRIBUTING I move all GitHub-recognized standard docs to root, like other repos I maintain. --- docs/contributing.md => CONTRIBUTING.md | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename docs/contributing.md => CONTRIBUTING.md (98%) diff --git a/docs/contributing.md b/CONTRIBUTING.md similarity index 98% rename from docs/contributing.md rename to CONTRIBUTING.md index 0cb2577d3..dcac3e308 100644 --- a/docs/contributing.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing +# How to Contribute ## Linting and Formatting diff --git a/README.md b/README.md index 2e4eadb85..b242f9869 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ Follow "Core-CMS" section of [How To Build & Deploy][Build & Deploy Project]. ## Contributing -To contribute, first read [How to Contirbute][Contributing]. +To contribute, first read [How to Contribute][Contributing]. ## Resources @@ -221,4 +221,4 @@ To contribute, first read [How to Contirbute][Contributing]. [Develop Project]: ./docs/develop-project.md [Upgrade Project]: ./docs/upgrade-project.md [Debug Project]: ./docs/debug-project.md -[Contributing]: ./docs/contributing.md +[Contributing]: ./CONTRIBUTING.md From 7b24129bb8ff66b0152a768450049dbc47f66f45 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Wed, 1 Oct 2025 14:36:49 -0500 Subject: [PATCH 33/60] chore: v4.36.5 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ed559c617..2d1ca35e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "4.36.4" +version = "4.36.5" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From b7a8e672d809ee710371a44879a55daa4ccddd19 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Wed, 1 Oct 2025 17:19:53 -0500 Subject: [PATCH 34/60] chore: poetry lock --- poetry.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9d86b1964..b75072546 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.4 and should not be changed by hand. [[package]] name = "aldryn-apphooks-config" @@ -2498,4 +2498,4 @@ testing = ["func-timeout", "jaraco.itertools"] [metadata] lock-version = "2.1" python-versions = ">=3.11,<4.0" -content-hash = "8ef7c041a1522e5e00995677cce04b851ebfd5852399795d29aa902b49526d21" +content-hash = "79b1550820b1e2ee49c161333d3490ea79dda9a58d048c66511e4470304dd3c5" From 7badb7741517a8536c9acb5b5f5565c1f959a513 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 2 Oct 2025 12:24:00 -0500 Subject: [PATCH 35/60] fix: djangocms-icon picker not showing Cortal icons (#995) --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- taccsite_cms/settings.py | 4 ++-- taccsite_cms/static/site_cms/img/icons/cortal.json | 9 +++++---- taccsite_cms/static/site_cms/img/icons/logos.json | 1 - .../admin/djangocms_icon/includes/assets.html | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/poetry.lock b/poetry.lock index b75072546..f684671c2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -847,18 +847,18 @@ django-filer = ">=1.7" [[package]] name = "djangocms-icon" -version = "2.0.0" +version = "2.1.0" description = "Adds icon plugin to django CMS." optional = false python-versions = "*" groups = ["main"] files = [ - {file = "djangocms-icon-2.0.0.tar.gz", hash = "sha256:47cb98354b1b4ff5115757b3e37c573148c017ec29fcf78721426589cefdfb6d"}, - {file = "djangocms_icon-2.0.0-py3-none-any.whl", hash = "sha256:c0074762e70d39e0bb4586d54f654c9345ec4387de9f73517e56fd937a5751ae"}, + {file = "djangocms-icon-2.1.0.tar.gz", hash = "sha256:1a356c07e4fd89c31919f440300f9f3d80a951491a41545285fe5cf22e59d62d"}, + {file = "djangocms_icon-2.1.0-py3-none-any.whl", hash = "sha256:be145e28c1f458fed5d96120a3147ff9373ea12540621e2ecf61a261b3b2af64"}, ] [package.dependencies] -django-cms = ">=3.7" +django-cms = ">=3.10" djangocms-attributes-field = ">=1" [[package]] @@ -2498,4 +2498,4 @@ testing = ["func-timeout", "jaraco.itertools"] [metadata] lock-version = "2.1" python-versions = ">=3.11,<4.0" -content-hash = "79b1550820b1e2ee49c161333d3490ea79dda9a58d048c66511e4470304dd3c5" +content-hash = "2ac17635289fc7cf2692591557221b048c40769a3ea1a108915ed19fc43cd098" diff --git a/pyproject.toml b/pyproject.toml index 2d1ca35e8..099f9f90c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ djangocms-column = "^2.0" djangocms-file = "3.0.0" djangocms-forms-maintained = { git = "https://github.com/TACC/djangocms-forms", rev = "6b59ff366495915f06f4d6fac01a2f0aa9efecaf" } djangocms-googlemap = "2.0.0" -djangocms-icon = "2.0.0" +djangocms-icon = "^2.1.0" djangocms-link = "^3.1" djangocms-page-meta = "1.3.0" djangocms-picture = "3.0.0" diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index d5f200937..ed84ee4ec 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -750,8 +750,8 @@ def get_subdirs_as_module_names(path): CORTAL_ICONS = f.read() DJANGOCMS_ICON_SETS = [ - # The SVG icon set must be first or icon selection is not remembered on edit - # HELP: Icon previews are blank if editor switches from SVG set to icon set + # IMPORTANT: Each set must have same props, even if value is empty + # WARNING: Values in icon sets are not cleared when user changes set # https://github.com/django-cms/djangocms-icon/issues/9 (LOGO_ICONS, '', _('Logo SVGs')), (CORTAL_ICONS, 'icon', _('TACC "Cortal" Icons')), diff --git a/taccsite_cms/static/site_cms/img/icons/cortal.json b/taccsite_cms/static/site_cms/img/icons/cortal.json index 6e0cc63af..9ccc4d63b 100644 --- a/taccsite_cms/static/site_cms/img/icons/cortal.json +++ b/taccsite_cms/static/site_cms/img/icons/cortal.json @@ -1,6 +1,7 @@ { + "svg": false, + "spritePath": "", "iconClass": "icon", - "// icons": "https://github.com/TACC/Core-Styles/blob/main/src/lib/_imports/components/cortal.icon.font.css", "icons": [ "icon-add-file", "icon-alert", @@ -97,7 +98,7 @@ "icon-add-folder", "icon-add-project", "icon-extract", - "icon-compress", - "icon-pytorch" - ] + "icon-compress" + ], + "// icons": "https://github.com/TACC/Core-Styles/blob/v2.47.0/src/lib/_imports/components/cortal-icon-font.css#L77-L463" } diff --git a/taccsite_cms/static/site_cms/img/icons/logos.json b/taccsite_cms/static/site_cms/img/icons/logos.json index 7678986c0..acde4440a 100644 --- a/taccsite_cms/static/site_cms/img/icons/logos.json +++ b/taccsite_cms/static/site_cms/img/icons/logos.json @@ -1,7 +1,6 @@ { "svg": true, "spritePath": "site_cms/img/icons/logos.svg", - "// iconClass": "Must be blank or svg template hash includes a space", "iconClass": "", "icons": [ "tacc-formal-logo", diff --git a/taccsite_cms/templates/admin/djangocms_icon/includes/assets.html b/taccsite_cms/templates/admin/djangocms_icon/includes/assets.html index ac50054be..d329a770b 100644 --- a/taccsite_cms/templates/admin/djangocms_icon/includes/assets.html +++ b/taccsite_cms/templates/admin/djangocms_icon/includes/assets.html @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + \ No newline at end of file diff --git a/taccsite_cms/static/site_cms/img/org_logos/portal.png b/taccsite_cms/static/site_cms/img/org_logos/portal.png deleted file mode 100644 index 3ec463826af8c20f80ba704c2f22977dd4334284..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1913 zcmV-<2Zs2GP)36*LW^5qtmu02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00!YnL_t(|+U=Zaj2*=h$A4un zHV(VQB%J1OVvEB@;D{?&99~!sbJ!4pEG$_>5JV(Epb!N6T?UDZ?l zz;PVMaU92S9LI4S$8j9TaU92S9LI5-@3Ce#C}|?_GvF{_Z(s(nGw>tehrkbjO~86! z2v`fO0#=yWznb_C#{i4dci9!_20jGd2Oa~Knb{i!+dcp|9GC^{nU3$rX&;k-4Z#0_ zH-Q0QIq-y;$yII(N751%XPu<;B~56c|AQs1$=Tl>lD2Kp_}-RuPMv){uX31QU|x5T z^lhZQ=Nif!}qI+uQ>jRpYT=xPdgr!@zdHy5ozO>lJ;$2e2=7u5M96yzzM*E8P8uL zY5NY*lM~a!hfJey;VwKbgY^3|>YN~HI8yJr8vX4qX(Ui@L{eYi`7TK-B7Oa(+2fOR zZbqe6xb^8vXn=(8s2LY>5ZyC17R`1Gh(tkF8Pt^oVP9ubHg~^fdyU4}^|f z7f71ic*tqSy}uH$H)2Kqw>5Y1j-+(5qP^@w~@8YG5Rw<$mT!*1H)tF-6hSR8%V0uF?u5MeIjF6V`jrO`db~5&njVTu|tS$IzUGj1Z0nz z*#_W+K-tM|AmxyC0x}el$4;Hz%F$o!nb{?bZO=N#Rh9T-4#^4NXg)Brwdvo>1JzD) z11X37BJwZI?2Aa*%!vGx9Q}P7kxy?V)g{8>i2RL;>qqG0-{YhH4jIT#8$2#|1F2Jq z{*zH>+XhzVp^Q0cn(HI!+zhwlnGTFU{yFOJ0g@A~aqDJP!ayXQ0h|#je!M_z@@1_) z)8pQeNO5-qW0@prnxqAi`iY;W3Am@i?$tDstmUz+95sjEkYr+yTLbB8VP6X+-2>bL zJWG=PejsoruqY$AU6#>iOp!-&zSD4I4vHAaX_D$mXTQ(P1}m%^C$o8S;%8>|-!Zc1 zNHP>gGgs17GaGUP$ z$ts0S4p$oK#K7d@G(hxNk8xh;1DyLZDx1Y zad$hm66Z-Hk3I9hf_KLsu$0sYLLVZhlceTXoo226$GCwMP#`m#VrDy;*(@_V&CISe zvw;F_u8GKJO?H&O0a{M3MK+3|*Hbw%+Zo*l zayxKYfvSVRiK#18CU+7}joF)O+`^kfIJ;n&Brh%xFGb`>xPer|NUk7B=Xf{IqM5or z2ecw_(9G5YcSVXXuE6xoi^$icJ769LGUAYq)HP!qB54xIZ#gXj_6K$$`8M)V8jm~z z+-+uW;W&=tIF92uj^j9v<2a7vIF92uTOi*7L5of`p4>6(00000NkvXXu0mjfooa-M From 94f2356f9672e84cdaba409daa19ac54e8a1429c Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Mon, 6 Oct 2025 18:38:54 -0500 Subject: [PATCH 40/60] refactor: from portal.png to logo.svg (#1001) --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 276eaf0c7..b3ecba07d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "minimist": "^1.2.6" }, "devDependencies": { - "@tacc/core-styles": "^2.46.2" + "@tacc/core-styles": "^2.47.1" }, "engines": { "node": ">=16", @@ -1132,9 +1132,9 @@ } }, "node_modules/@tacc/core-styles": { - "version": "2.46.2", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.2.tgz", - "integrity": "sha512-b3MTccuLswbJM19ysX85vHYt6l/hHtvEgR3ZhKZZvoVXPBZjyfhl9zvnOrnQPB5tnLMt59nKdyHo+XcEj67lgA==", + "version": "2.47.1", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.47.1.tgz", + "integrity": "sha512-XnfJaR/akvIu2iTHXxLvFSenSUwv9snnkq1zfTqNhqm5UoXqBpBGGfnH9ts7+geSsgdpk7gQ4rUzwHgPQNyO1Q==", "dev": true, "license": "MIT", "bin": { @@ -4733,9 +4733,9 @@ } }, "@tacc/core-styles": { - "version": "2.46.2", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.46.2.tgz", - "integrity": "sha512-b3MTccuLswbJM19ysX85vHYt6l/hHtvEgR3ZhKZZvoVXPBZjyfhl9zvnOrnQPB5tnLMt59nKdyHo+XcEj67lgA==", + "version": "2.47.1", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.47.1.tgz", + "integrity": "sha512-XnfJaR/akvIu2iTHXxLvFSenSUwv9snnkq1zfTqNhqm5UoXqBpBGGfnH9ts7+geSsgdpk7gQ4rUzwHgPQNyO1Q==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 23b32a020..540c64050 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,6 @@ }, "homepage": "https://github.com/TACC/Core-CMS", "devDependencies": { - "@tacc/core-styles": "^2.46.2" + "@tacc/core-styles": "^2.47.1" } } From 0b24eb3435ae05ceaac7191851a16cafb71d6b56 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 14 Oct 2025 18:48:27 -0500 Subject: [PATCH 41/60] refactor: no need to annotate tags (#1006) --- CONTRIBUTING.md | 7 +------ Makefile | 2 +- bin/annotate-tag.sh | 37 ------------------------------------- bin/build-css.js | 3 ++- bin/git-describe.js | 19 +++++++++++++++++++ 5 files changed, 23 insertions(+), 45 deletions(-) delete mode 100755 bin/annotate-tag.sh create mode 100644 bin/git-describe.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dcac3e308..99d7cafdf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,12 +43,7 @@ Only appointed team members may release versions. - `poetry version N.N.N` 2. Review. Commit. Push. 3. Create release and tag on GitHub. -4. Annotate Github's tag:\ - `bin/annotate-tag.sh vN.N.N`\ - (where `N.N.N` is the version tag) -5. Overwrite remote tag with annotated one:\ - `git push --tags --force` -6. [Build & Deploy](../README.md#build--deploy-project) `main` branch.[^1] +4. [Build & Deploy](../README.md#build--deploy-project) `main` branch.[^1] [^1]: So that new CMS image is tagged `latest` and `vN.N.N`. diff --git a/Makefile b/Makefile index 04ac8de0e..e023fb43a 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DOCKER_COMPOSE_CMD := $(shell if command -v docker-compose > /dev/null; then ech # NOTE: Special characters in `DOCKER_IMAGE_BRANCH` are replaced with dashes. DOCKER_IMAGE_BRANCH := $(DOCKERHUB_REPO):$(shell git describe --exact-match --tags 2> /dev/null || git symbolic-ref --short HEAD | sed 's/[^[:alnum:]\.\_\-]/-/g') -BUILD_ID := $(shell git describe --always) +BUILD_ID := $(shell git describe --tags) .PHONY: build build: diff --git a/bin/annotate-tag.sh b/bin/annotate-tag.sh deleted file mode 100755 index 4538a92c7..000000000 --- a/bin/annotate-tag.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -# Annotate a tag from Github -# FAQ: Github releases create annotated (not lightweight) tags -# SEE: https://github.com/orgs/community/discussions/4924 - -# Whether string is a valid SemVer version -is_valid_semver() { - local version=$1 - # SemVer regex pattern (simplified for illustration) - local semver_pattern="^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$" - [[ $version =~ $semver_pattern ]] -} - -# Is argument (string) provided? -if [ $# -ne 1 ]; then - echo "Usage: $0 " - exit 1 -fi - -# Capture arguments -version_string=$1 - -# Is string a valid SemVer version? -if ! is_valid_semver "$version_string"; then - echo "Error: Invalid SemVer format. Please provide a valid version string like '3.11.6' or 'v3.12.0-beta.3' or 'v3.6.0-8-gd1dbcab'." - exit 1 -fi - -# Annotate the tag -git pull -git checkout "$version_string" -git tag -d "$version_string" -git tag -a "$version_string" -m "chore: $version_string" - -# Report success -echo "Annotated tag \"$version_string\"." diff --git a/bin/build-css.js b/bin/build-css.js index 9b4efb545..37fedea3a 100755 --- a/bin/build-css.js +++ b/bin/build-css.js @@ -4,10 +4,11 @@ const buildStylesheets = require('@tacc/core-styles').buildStylesheets; const mininmist = require('minimist'); +const gitDescribe = require('./git-describe'); const ROOT = __dirname + '/..'; const ARGS = mininmist( process.argv.slice( 2 ) ); -const BUILD_ID = ARGS['build-id'] || ''; +const BUILD_ID = ARGS['build-id'] || gitDescribe(); /** Build stylesheets */ (() => { diff --git a/bin/git-describe.js b/bin/git-describe.js new file mode 100644 index 000000000..1bde0bcc3 --- /dev/null +++ b/bin/git-describe.js @@ -0,0 +1,19 @@ +#!/usr/bin/env node + +/** Get tag-based description from Git */ +function gitDescribe() { + const { execSync } = require('child_process'); + + let gitDescribe = undefined; + + try { + gitDescribe = execSync('git describe --tags', { encoding: 'utf8' }).trim(); + console.log('Output from `git describe`:', gitDescribe); + } catch (error) { + console.error('Error running `git describe`:', error.message); + } + + return gitDescribe; +} + +module.exports = gitDescribe; From c90889a2a11e43ee449a85ab6f903493d9483955 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 14 Oct 2025 19:01:42 -0500 Subject: [PATCH 42/60] chore: v4.35.7 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2fdd44daa..42cb08465 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "4.36.6" +version = "v4.35.7" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From c8eb94fe2b3c9f8808f1538bb8567956a72049cd Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 16 Oct 2025 14:57:05 -0500 Subject: [PATCH 43/60] fix: image caption breaks alignment (old styles) (#1009) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * **adds** — ```css .align-center:not(img):has(img){ width:fit-content; } ``` — to `site.css` (outdated) * **deletes** warnings about bug * **updates** translations --- taccsite_cms/locale/en/LC_MESSAGES/django.mo | Bin 2248 -> 1828 bytes taccsite_cms/locale/en/LC_MESSAGES/django.po | 12 ------------ .../css/src/_migrations/v3-10_v3-11/site.css | 2 +- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/taccsite_cms/locale/en/LC_MESSAGES/django.mo b/taccsite_cms/locale/en/LC_MESSAGES/django.mo index b103b5bdfdb924d7c7d59e11507626285e630658..151270143338f2eec220c1a1ee99c63e1f149a9b 100644 GIT binary patch delta 299 zcmX>hxP-6%o)F7a1|Z-9Vi_RL0b*Vt-UGxS@BxVZfcPU2M*y({BSg(iAe{!}voSF+ zL;>ksARP;&PXK8aAg#vCz`y~dwShDzkTwC*kAbuuknRT3NYr$`4ihUMgX>_CglJC delta 722 zcmbu6u}d656vp3PZcQ#Z1cRl>yDL)36#*Nu@FGEk6Vb@B;iz zG@?J4Xe^wgY7DOXL?_@3{0OFVL__c|XzLCh{u87BMntRz zMykA3Hmb|zyf=Qaqt&5|aDpRIgj%}o6%LHia{ryJUExp-jyE3)J!*JIo!`qWyYc3p`qr<4 R&vwoJ8helCwB!Hqt^rfHv}*tW diff --git a/taccsite_cms/locale/en/LC_MESSAGES/django.po b/taccsite_cms/locale/en/LC_MESSAGES/django.po index 58345cf67..3541401f5 100644 --- a/taccsite_cms/locale/en/LC_MESSAGES/django.po +++ b/taccsite_cms/locale/en/LC_MESSAGES/django.po @@ -91,18 +91,6 @@ msgstr "Next" -#: djangocms-picture -#: models.py:117 -msgid "Aligns the image according to the selected option." -msgstr "Aligns the image according to the selected option. WARNING: Alignment behavior changes if \"Caption text\" is added." - -#: djangocms-picture -#: models.py:123 -msgid "Provide a description, attribution, copyright or other information." -msgstr "Provide a description, attribution, copyright or other information. WARNING: Adding caption text will change the behavior of \"Alignment\"." - - - #: site-cms(djangocms-blog) #: templates/djangocms_blog/includes/blog_meta.html:6 msgid "To be published" diff --git a/taccsite_cms/static/site_cms/css/src/_migrations/v3-10_v3-11/site.css b/taccsite_cms/static/site_cms/css/src/_migrations/v3-10_v3-11/site.css index a984b691b..b2e64a62d 100644 --- a/taccsite_cms/static/site_cms/css/src/_migrations/v3-10_v3-11/site.css +++ b/taccsite_cms/static/site_cms/css/src/_migrations/v3-10_v3-11/site.css @@ -1 +1 @@ -/*! @tacc/core-cms v3.10.1 | MIT | github.com/TACC/Core-CMS *//*! EDITS: TACC/Core-CMS#660 */@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap");:root{--header-text-color:var(--global-color-primary--xx-light);--header-bkgd-color:var(--global-color-primary--xx-dark);--header-minor-border-color:var(--global-color-primary--normal);--header-major-border-color:var(--header-bkgd-color);--header-search-brdr-color:var(--global-color-primary--dark);--header-search-bkgd-color:#313131;--menu-toggle-icon:none}:root{--global-border-width--normal:1px;--global-border--normal:var(--global-border-width--normal) solid var(--global-color-primary--normal);--global-border-width--thick:2px;--global-border--thick:var(--global-border-width--thick) solid var(--global-color-primary--normal);--global-border-width--x-thick:3px;--global-border--x-thick:var(--global-border-width--x-thick) solid var(--global-color-primary--normal)}:root{--global-max-width--x-narrow:540px;--global-max-width--narrow:720px;--global-max-width--medium:960px;--global-max-width--wide:1140px;--global-max-width--x-wide:1320px;--global-max-width--xx-wide:1580px;--global-max-width--xxx-wide:1800px}:root{--global-space--xx-small:2px;--global-space--x-small:4px;--global-space--small:8px;--global-space--normal:16px;--global-space--large:24px;--global-space--x-large:48px;--global-space--list-indent:40px;--global-space--section-gap:45px;--global-space--grid-gap:15px;--global-space--section-top:12px;--global-space--section-bottom:0;--global-space--section-left:24px;--global-space--section-right:36px;--global-space--section:var(--global-space--section-top) var(--global-space--section-right) var(--global-space--section-bottom) var(--global-space--section-left);--global-space--hr-buffer-above:10px;--global-space--hr-buffer-below:30px}:root{--global-color-primary--xx-light:#fff;--global-color-primary--xx-light-rgb:255,255,255;--global-color-primary--x-light:#f4f4f4;--global-color-primary--x-light-rgb:244,244,244;--global-color-primary--light:#c6c6c6;--global-color-primary--normal:#afafaf;--global-color-primary--dark:#707070;--global-color-primary--x-dark:#484848;--global-color-primary--x-dark-rgb:72,72,72;--global-color-primary--xx-dark:#222;--global-color-primary--xx-dark-rgb:34,34,34;--global-color-accent--x-light:#AAC7FF;--global-color-accent--light:#86aeff;--global-color-accent--normal:#003399;--global-color-accent--dark:#002266;--global-color-accent--x-dark:#001133;--global-color-accent--alt:#cbd4e7;--global-color-accent--weak:#00226640;--global-color-info--dark:var(--global-color-primary--x-dark);--global-color-info--normal:var(--global-color-primary--normal);--global-color-info--light:var(--global-color-primary--x-light);--global-color-success--dark:#237119;--global-color-success--normal:#43d130;--global-color-success--weak:#43d13020;--global-color-success--alt:var(--global-color-warning--normal);--global-color-success--alt-weak:var(--global-color-warning--weak);--global-color-warning--dark:#717411;--global-color-warning--normal:#c7ce1d;--global-color-warning--weak:#c7ce1d20;--global-color-warning--alt:var(--global-color-accent--dark);--global-color-warning--alt-weak:var(--global-color-accent--weak);--global-color-danger--dark:#af1818;--global-color-danger--normal:#f09393;--global-color-danger--weak:#f0939320;--global-color-background--app:var(--global-color-primary--xx-light);--global-color-link-on-light--normal:var(--global-color-accent--normal);--global-color-link-on-dark--normal:var(--global-color-accent--light)}@font-face{font-display:swap;font-family:Benton Sans;font-style:normal;font-weight:400;src:url(/static/site_cms/fonts/BentonSans-Regular.otf) format("opentype")}@font-face{font-display:swap;font-family:Benton Sans;font-style:normal;font-weight:700;src:url(/static/site_cms/fonts/BentonSans-Bold.otf) format("opentype")}@font-face{font-display:swap;font-family:Benton Sans;font-style:normal;font-weight:500;src:url(/static/site_cms/fonts/BentonSans-Medium.otf) format("opentype")}@font-face{font-display:swap;font-family:Benton Sans;font-style:italic;font-weight:500;src:url(/static/site_cms/fonts/BentonSans-MediumItalic.otf) format("opentype")}:root{--global-font-family--sans--cms:"Benton Sans","Roboto",sans-serif;--global-font-family--sans--portal:"Roboto",sans-serif;--global-font-family--serif:Times,sans-serif;--global-font-family--mono:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace;--global-font-size--x-small:1.1rem;--global-font-size--small:1.4rem;--global-font-size--medium:1.6rem;--global-font-size--large:2.0rem;--global-font-size--x-large:2.6rem;--global-font-size--xx-large:3.2rem;--global-font-size--xxx-large:4.1rem;--global-font-weight--regular:400;--global-font-weight--medium:500;--global-font-weight--bold:700;--regular:400;--medium:500;--bold:700}:root{--global-font-family--sans:var(--global-font-family--sans--cms);--global-font-family:var(--global-font-family--sans);--font-family-sans-serif:var(--global-font-family--sans);--font-family-monospace:var(--global-font-family--mono)}html{font-size:62.5%}body,html{height:100%}body{color:var(--global-color-primary--x-dark);font-family:var(--global-font-family--sans--cms);font-size:var(--global-font-size--medium);line-height:1.4;min-width:290px}body>main{margin-bottom:var(--global-space--section-gap)}body>main+footer{position:sticky;top:100vh}h1,h2,h3,h4,h5,h6{color:var(--global-color-primary--xx-dark)}h1,h2,h4,h5,h6{font-weight:var(--bold)}h1{margin-bottom:27px;margin-top:27px}h2{margin-bottom:var(--global-space--normal);margin-top:30px}h1+h2,h1+hr{margin-top:-12px}h1{font-size:var(--global-font-size--xxx-large)}h2{font-size:var(--global-font-size--x-large)}h3,h4,h5,h6{margin-bottom:var(--global-space--normal);margin-top:var(--global-space--normal)}h3{font-size:var(--global-font-size--x-large)}h4{font-size:var(--global-font-size--large)}h5{text-transform:uppercase}h5,h6{font-size:var(--global-font-size--medium)}p{margin-bottom:2rem}dl dl,ol,ul{padding-left:var(--global-space--list-indent)}ol ol,ol ul,ul ol,ul ul{margin:revert}dt{font-weight:400;margin-bottom:.5rem}li:not(td li){line-height:1.6}hr{border-top:1px solid var(--global-color-primary--light);margin-bottom:var(--global-space--hr-buffer-below);margin-top:var(--global-space--hr-buffer-above)}code,kbd,pre,samp,var{font-family:var(--global-font-family--mono)}code kbd{display:inline-block;font-size:inherit;margin-left:.2rem;margin-right:.2rem;padding:.1rem .2rem}code,pre>samp{color:unset}:not(pre)>code{display:inline-block;padding:var(--global-space--xx-small) var(--global-space--x-small)}pre>code,pre>samp{display:inline-block;padding:var(--global-space--x-small) var(--global-space--small)}pre[style]>code,pre[style]>samp{min-width:100%}pre samp{opacity:.75;text-decoration:none}pre code u{opacity:.5;text-decoration:none}details{margin-bottom:1rem;margin-top:0}input,label,select,textarea{font-family:var(--global-font-family--sans--portal)}label{font-size:var(--global-font-size--small);line-height:normal;margin-bottom:.75em}li>label:only-child{margin-bottom:unset}:not(input[type=checkbox])+label{display:block}fieldset:not(:last-child){margin-bottom:3.5rem}input,select,textarea{border:var(--global-border--normal)}::-moz-placeholder{color:var(--global-color-primary--dark)}::placeholder{color:var(--global-color-primary--dark)}input[type=date],input[type=time]{font-family:var(--global-font-family--mono)}input:not([type=time],[type=date],[type=checkbox],[type=radio]),select,textarea{max-width:50ch}input:where([type=time],[type=date],[type=checkbox],[type=radio]){width:-moz-min-content;width:min-content}@media (pointer:coarse){input,select,textarea{padding:12px}}@media (pointer:fine),(pointer:none){input,select,textarea{padding:5px 10px}}.c-button--as-link,.s-irregular-links .c-button--as-link,.s-irregular-links a,.x-link,.x-link--irregular,a{color:var(--global-color-link-on-light--normal);text-decoration:none;text-decoration-thickness:var(--global-border-width--normal);text-underline-offset:.2em}.c-button--as-link:where(:not(:disabled,:where(a[disabled]))):hover,.s-irregular-links .c-button--as-link:hover,.s-irregular-links a:hover,.x-link--hover,.x-link--irregular--hover,a:hover{color:var(--global-color-link-on-light--normal);text-decoration-line:underline;text-decoration-style:solid;text-decoration-thickness:var(--global-border-width--normal)}.c-button--as-link:active,.s-irregular-links .c-button--as-link:active,.s-irregular-links a:active,.x-link--active,.x-link--irregular--active,a:active{text-decoration-line:underline;text-decoration-style:dotted}.s-irregular-links .c-button--as-link,.s-irregular-links a,.x-link--irregular{text-decoration-line:underline}.s-irregular-links .c-button--as-link:hover,.s-irregular-links a:hover,.x-link--irregular--hover{text-decoration-style:dashed}.s-irregular-links .c-button--as-link:active,.s-irregular-links a:active,.x-link--irregular--active{text-decoration-style:dotted}.x-truncate--many-lines,table p{--lines:2;-webkit-box-orient:vertical;-webkit-line-clamp:var(--lines);display:-webkit-box;overflow:hidden}.x-untruncate--many-lines{-webkit-line-clamp:inherit;overflow:visible}.button-wrapper button[type=submit],.c-button,.c-data-list--should-truncate-values .c-data-list__value,.c-data-list__key,.c-see-all-link,.form-button,.modal-title,.x-truncate--one-line{overflow:hidden;text-overflow:var(--text-overflow,ellipsis);white-space:nowrap}.x-untruncate--one-line{overflow:visible;white-space:normal}table{border-collapse:separate;border-spacing:0;font-family:var(--global-font-family--sans--portal);font-size:var(--global-font-size--small)}thead tr :is(td,th),tr:not(:last-of-type)>:is(td,th){border-bottom:var(--global-border--normal)}tr:nth-child(odd) :is(th,td){background:var(--global-color-background--app)}tr:nth-child(2n) :is(th,td){background:var(--global-color-primary--x-light)}:is(td,th){color:var(--global-color-primary--dark);padding-block:8px;padding-inline:16px;vertical-align:top}:is(td,th){line-height:var(--global-font-size--medium)}:is(th,td):first-child{border-right:var(--global-border-width--normal) solid var(--global-color-primary--light);left:0;position:sticky}th{color:var(--global-color-primary--x-dark);text-align:inherit}thead>tr>th{font-weight:var(--bold)}tbody>tr>th{font-weight:var(--normal)}caption{font-size:var(--global-font-size--small);text-align:unset}td ul{-webkit-padding-start:0;list-style:none;margin-block:0;padding-inline-start:0}td li:not(:last-of-type){margin-bottom:.5em}td button{font-size:inherit}table p{margin-top:0}table p:last-child{margin-bottom:0}@supports selector(:has(table)){table:has(table) :is(td,th){white-space:nowrap}table:has(table) tr:nth-child(2n) :is(th,td){background:var(--global-color-background--app)}td:has(table) tr:nth-child(2n) :is(th,td){background:var(--global-color-primary--x-light)}td:has(table){padding:0}}@supports not selector(:has(table)){table.has-table :is(td,th){white-space:nowrap}table.has-table tr:nth-child(2n) :is(th,td){background:var(--global-color-background--app)}td.has-table tr:nth-child(2n) :is(th,td){background:var(--global-color-primary--x-light)}td.has-table{padding:0}}tr table{--offset:-33px;margin-bottom:var(--offset);transform:translateY(var(--offset))}tr:first-of-type thead{background:var(--global-color-background--app)}tr:not(:first-of-type) thead{visibility:hidden}td:not(:first-child) td:first-child,td:not(:first-child) th:first-child{-webkit-padding-start:8px;padding-inline-start:8px}td:not(:last-child) td:last-child,td:not(:last-child) th:last-child{-webkit-padding-end:8px;padding-inline-end:8px}.o-grid--col-auto-count{grid-template-columns:repeat(var(--count),auto)}.o-grid--col-min-width{grid-template-columns:repeat(auto-fit,minmax(var(--width),1fr))}.o-grid{grid-auto-rows:1fr}.o-grid--center-align{align-items:center;justify-items:center}.o-grid{--gap:var(--global-space--grid-gap,15px);display:grid;gap:var(--gap)}.o-grid img{max-height:100%;max-width:100%}.o-grid>*{overflow:hidden}@media (max-width:575px){.o-grid--col-auto-count{--count:1}}@media (min-width:576px) and (max-width:767px){.o-grid--col-auto-count{--count:2}}@media (min-width:768px) and (max-width:991px){.o-grid--col-auto-count{--count:3}}@media (min-width:992px) and (max-width:1199px){.o-grid--col-auto-count{--count:4}}@media (min-width:1200px) and (max-width:1399px){.o-grid--col-auto-count{--count:5}}@media (min-width:1400px) and (max-width:1679px){.o-grid--col-auto-count{--count:6}}@media (min-width:1680px) and (max-width:1919px){.o-grid--col-auto-count{--count:7}}@media (min-width:1920px) and (max-width:2399px){.o-grid--col-auto-count{--count:8}}@media (min-width:2400px){.o-grid--col-auto-count{--count:9}}.o-grid--col-min-width{--width:250px}.o-grid--col-min-width>:not(img){max-height:100%;max-width:100%}.o-grid--image-fill>:is(a,figure):not(img){height:100%;width:100%}.o-grid--image-fill>a>img:only-child,.o-grid--image-fill>figure>img,.o-grid--image-fill>img{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.o-grid--image-fill>figure:not([class]),.o-grid--image-fill>figure[class*=cms-plugin],.o-grid--image-fill>figure[class=""]{display:flex;flex-direction:column}.o-grid--image-fill>figure:not([class])>img,.o-grid--image-fill>figure[class*=cms-plugin]>img,.o-grid--image-fill>figure[class=""]>img{flex-grow:1;min-height:0}.o-float-content--left,.o-float-content--right{--buffer:calc(var(--global-space--grid-gap)*2)}@media only screen and (min-width:992px){.o-float-content--right{float:right;margin-left:var(--buffer)}.o-float-content--right+.o-float-content--right{clear:right}.o-float-content--left{float:left;margin-right:var(--buffer)}.o-float-content--left+.o-float-content--left{clear:left}.figure:is(.o-float-content--left,.o-float-content--right) .figure-caption{padding-right:125px}}@media only screen and (min-width:992px) and (max-width:2399px){.o-float-content--left,.o-float-content--right{max-width:560px}}.o-offset-content--left,.o-offset-content--right{--offset-distance:min(15vw,410px);--buffer:calc(var(--global-space--grid-gap)*2)}@media only screen and (min-width:992px){.o-offset-content--right{float:right;margin-left:var(--buffer)}.o-offset-content--right+.o-offset-content--right{clear:right}.o-offset-content--left{float:left;margin-right:var(--buffer)}.o-offset-content--left+.o-offset-content--left{clear:left}.figure:is(.o-offset-content--left,.o-offset-content--right) .figure-caption{padding-right:125px}}@media only screen and (min-width:992px) and (max-width:2399px){.o-offset-content--left,.o-offset-content--right{max-width:560px}.o-offset-content--right{margin-right:calc(var(--offset-distance)*-1)}.o-offset-content--left{margin-left:calc(var(--offset-distance)*-1)}}.o-section--layout-a,.o-section--layout-b,.o-section--layout-c,.o-section--layout-d,.x-layout--a,.x-layout--b,.x-layout--c,.x-layout--d{display:grid}@media (max-width:991px){.o-section--layout-a,.x-layout--a{grid-template-columns:repeat(1,minmax(0,1fr))}}@media (min-width:992px){.o-section--layout-a,.x-layout--a{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:991px){.o-section--layout-b,.x-layout--b{grid-template-columns:minmax(0,1fr)}}@media (min-width:992px){.o-section--layout-b,.x-layout--b{grid-template-columns:minmax(0,2fr) minmax(0,1fr)}}@media (max-width:991px){.o-section--layout-c,.x-layout--c{grid-template-columns:minmax(0,1fr)}}@media (min-width:992px){.o-section--layout-c,.x-layout--c{grid-template-columns:minmax(0,1fr) minmax(0,2fr)}}@media (max-width:575px){.o-section--layout-d,.x-layout--d{grid-template-columns:repeat(1,minmax(0,1fr))}}@media (min-width:576px) and (max-width:767px),(min-width:768px) and (max-width:991px){.o-section--layout-d,.x-layout--d{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:992px){.o-section--layout-d,.x-layout--d{grid-template-columns:repeat(3,minmax(0,1fr))}}.x-layout--e{display:flex;flex-direction:column}.o-section--style-dark+.o-section--style-dark.container,.o-section--style-light+.o-section--style-light.container{--fb--line-width:0px;--fb--line-color:transparent;--fb--inset-width:0px;--fb--inset-color:transparent;--fb--start:inset calc(var(--fb--inset-width)*1) 0 var(--fb--inset-color);--fb--end:inset calc(var(--fb--inset-width)*-1) 0 var(--fb--inset-color);--fb:var(--fb--start),var(--fb--end),var(--fb--line);box-shadow:var(--fb--shadow-above,0 0 transparent),var(--fb),var(--fb--shadow-below,0 0 transparent)}.o-section--style-dark+.o-section--style-dark.container,.o-section--style-light+.o-section--style-light.container{--fb--line:inset 0 calc(var(--fb--line-width)*1) var(--fb--line-color)}.o-section{--padding-block:var(--global-space--section-gap);padding-block:var(--padding-block)}.o-section .o-section{--hoz-space:1em;margin-inline:calc(var(--hoz-space)*-1);padding-block:1em;padding-inline:var(--hoz-space)}.o-section--banner{overflow:hidden}.o-section--banner [class*=o-section--layout]{gap:0}.o-section--banner .container{padding-inline:0}.o-section--banner.o-section{padding-block:0}.o-section--intro .u-empty,.o-section--intro>:empty:not(img){display:none}.o-section--style-light{--color--text:var(--global-color-primary--dark);--color--text-strong:var(--global-color-primary--xx-dark);--color--bkgd:var(--global-color-primary--xx-light);--color--line:var(--global-color-primary--normal);--color--link:var(--global-color-link-on-light--normal)}.o-section--style-muted{--color--text:var(--global-color-primary--x-dark);--color--text-strong:var(--global-color-primary--xx-dark);--color--bkgd:var(--global-color-primary--x-light);--color--line:var(--global-color-primary--dark);--color--link:var(--global-color-link-on-light--normal)}.o-section--style-dark{--color--text:var(--global-color-primary--x-light);--color--text-strong:var(--global-color-primary--xx-light);--color--bkgd:var(--global-color-primary--xx-dark);--color--line:var(--global-color-primary--xx-light);--color--link:var(--global-color-link-on-dark--normal)}[class*=o-section--style]{--line-width:var(--global-border-width--normal);--box-shadow--fake-bkgd:50vw 0 var(--color--bkgd),-50vw 0 var(--color--bkgd);background-color:var(--color--bkgd);box-shadow:var(--box-shadow--fake-bkgd);color:var(--color--text)}[class*=o-section--style] [class*=o-section--style]{box-shadow:none}.o-section--style-dark+.o-section--style-dark:not(.container),.o-section--style-light+.o-section--style-light:not(.container){border-top:var(--line-width) solid var(--color--line)}.o-section--style-muted{border-bottom:var(--line-width) solid var(--color--line);border-top:var(--line-width) solid var(--color--line)}.o-section--style-muted{--box-shadow--fake-bkgd:50vw 0 0 calc(var(--line-width)*-1) var(--color--bkgd),-50vw 0 0 calc(var(--line-width)*-1) var(--color--bkgd),33vw 0 var(--color--line),-33vw 0 var(--color--line),33vw 0px var(--color--line),-33vw 0px var(--color--line)}.o-section--style-dark+.o-section--style-dark.container,.o-section--style-light+.o-section--style-light.container{--fb--line-width:var(--global-border-width--normal);--fb--line-color:var(--color--line);--fb--inset-width:var(--global-space--grid-gap);--fb--inset-color:var(--color--bkgd);--fb--shadow-below:var(--box-shadow--fake-bkgd)}[class*=o-section--style] a{color:var(--color--link)}[class*=o-section--style] :is(h1,h2,h3,h4,h5,h6){color:var(--color--text-strong)}.o-section--layout-a,.o-section--layout-b,.o-section--layout-c,.o-section--layout-d{--gap:3.0rem;gap:var(--gap)}[class*=o-section--style].o-section--banner+[class*=o-section--style]{box-shadow:var(--box-shadow--fake-bkgd)}.o-section--banner .o-section__banner-image{left:50%;min-height:100%;-o-object-fit:cover;object-fit:cover;position:absolute;top:50%;transform:translate(-50%,-50%);width:100vw;z-index:1}.o-section--banner .o-section__banner-overlay{position:relative;z-index:2}main>.container.o-section--style-dark:last-of-type,main>.container.o-section--style-light:last-of-type,main>.container>.o-section--style-dark:last-of-type,main>.container>.o-section--style-light:last-of-type{margin-bottom:calc(var(--padding-block)*-1)}.x-article-link-stretch{height:100%;left:0;overflow:hidden;position:absolute;top:0;width:100%}.x-article-link-stretch--gapless{left:-15px;width:calc(100% + 30px)}.x-article-link-hover,a.c-callout:hover,a.c-card--frontera-about-page:hover{--outline-offset:1em;outline:1px solid var(--global-color-accent--normal);outline-offset:var(--outline-offset)}.x-article-link-hover--gapless{--outline-offset:0}a.c-callout:active,a.c-card--frontera-about-page:active{outline:1px dotted var(--global-color-accent--normal)}.c-card--frontera-about-page{border-bottom:var(--global-border-width--normal) solid var(--global-color-primary--dark);margin-bottom:4.6rem;width:-moz-fit-content;width:fit-content}a.c-card--frontera-about-page{display:inline-block;text-decoration:none}.c-card--frontera-about-page img+h3{margin-top:1.6rem}.c-card--frontera-about-page img~:last-child{margin-bottom:1.25rem}.c-card--frontera-about-page figure{margin:0}.c-card--frontera-about-page figcaption{color:var(--global-color-primary--xx-dark);font-size:var(--global-font-size--x-large);font-weight:var(--bold);margin-bottom:1.25rem;margin-top:1.6rem}.c-callout{--figure-width--no-units:310;--figure-height--no-units:130;display:grid}.c-callout>:is(img,figure){grid-area:figure}.c-callout>:is(h1,h2,h3,h4,h5,h6){grid-area:title}.c-callout>p{grid-area:desc}.c-callout>p{margin-top:0}.c-callout>figure>img,.c-callout>img{aspect-ratio:var(--figure-width--no-units) /var(--figure-height--no-units);-o-object-fit:cover;object-fit:cover}.c-callout>figure{width:-moz-min-content;width:min-content}@media only screen and (min-width:768px){.c-callout{grid-template-areas:"figure title" "figure desc";grid-template-columns:min-content auto;grid-template-rows:auto min-content;padding:20px;text-align:left}.c-callout>figure{margin:0}.c-callout>:is(img,figure){margin-right:40px}.c-callout>figure>img,.c-callout>img{max-width:-moz-fit-content;max-width:fit-content;width:calc(var(--figure-width--no-units)*1px)}.c-callout>img{min-height:100%}}@media only screen and (max-width:767px){.c-callout{grid-template-areas:"figure" "title" "desc";padding:20px 40px;text-align:center}.c-callout>figure{margin:0}.c-callout>:is(img,figure){margin-bottom:20px}.c-callout>figure>img,.c-callout>img{height:calc(var(--figure-height--no-units)*1px);max-height:-moz-fit-content;max-height:fit-content}.c-callout>img{min-width:100%}}.c-callout>:is(img,figure){place-self:center}.c-callout>p{padding-right:1%}.c-callout{background-color:var(--global-color-link-on-light--normal)}.c-callout>:is(h1,h2,h3,h4,h5,h6){border-bottom:1px solid var(--global-color-primary--xx-light);font-size:var(--global-font-size--x-large);font-weight:var(--medium);margin-bottom:12px;margin-top:0;padding-bottom:12px}.c-callout>:is(h1,h2,h3,h4,h5,h6),[class*=o-section--style] .c-callout>:is(h1,h2,h3,h4,h5,h6){color:var(--global-color-primary--xx-light)}.c-callout>:not(h1,h2,h3,h4,h5,h6){color:var(--global-color-primary--xx-light)}.c-callout>:not(h1,h2,h3,h4,h5,h6,figure){font-size:var(--global-font-size--large);font-weight:var(--medium)}a.c-callout:hover{text-decoration:none}a.c-callout:focus{text-decoration:none}table.c-data-list{border-left:0;border-right:0}@supports(text-overflow:":"){.c-data-list__key:not(th){--text-overflow:":"}}td.c-data-list__value,th.c-data-list__key{padding-block:.5em}.c-data-list__key:not(th):after{content:":";display:inline;padding-right:.25em}th.c-data-list__key{padding-right:.25em}.c-data-list--is-horz{display:flex;flex-direction:row}.c-data-list--is-horz dd.c-data-list__value,dl.c-data-list--is-horz{margin-bottom:0}table.c-data-list--is-horz tbody,table.c-data-list--is-horz tr{display:flex;flex-direction:row;min-width:0}.c-data-list--is-horz:not(table).c-data-list--is-narrow>.c-data-list__key~.c-data-list__key:before{padding-left:.5em;padding-right:.5em}.c-data-list--is-horz:not(table).c-data-list--is-wide>.c-data-list__key~.c-data-list__key:before{padding-left:1em;padding-right:1em}table.c-data-list--is-horz.c-data-list--is-narrow tr:not(:first-child) th.c-data-list__key{padding-left:.5em}table.c-data-list--is-horz.c-data-list--is-narrow td.c-data-list__value{margin-right:.5em}table.c-data-list--is-horz.c-data-list--is-wide tr:not(:first-child) th.c-data-list__key{padding-left:1em}table.c-data-list--is-horz.c-data-list--is-wide td.c-data-list__value{margin-right:1em}table.c-data-list--is-vert{table-layout:fixed;width:100%}.c-data-list--is-vert:not(table)>.c-data-list__value{margin-left:0}.c-data-list--is-vert:not(table).c-data-list--is-narrow>.c-data-list__value,table.c-data-list--is-vert.c-data-list--is-narrow td.c-data-list__value{padding-left:0}.c-data-list--is-vert:not(table).c-data-list--is-wide>.c-data-list__value,table.c-data-list--is-vert.c-data-list--is-wide td.c-data-list__value{padding-left:2.5em}table.c-data-list--is-vert th.c-data-list__key,td.c-data-list__value{border-left:0;border-right:0}table.c-data-list--is-horz td.c-data-list__value,table.c-data-list--is-horz th.c-data-list__key{border-bottom:0;border-top:0}table.c-data-list--is-horz tr:first-child th.c-data-list__key{border-left:0}table.c-data-list--is-horz th.c-data-list__key{border-right:0}.c-data-list--is-horz:not(table)>.c-data-list__key~.c-data-list__key:before{content:"|";display:inline-block}.c-data-list--is-horz:not(table){align-items:baseline}table.c-data-list--is-horz tr{align-items:baseline}table.c-data-list--is-vert td.c-data-list__value,table.c-data-list--is-vert th.c-data-list__key{vertical-align:baseline}nav.c-nav{--link-padding:0.5em}nav.c-nav--boxed{--indent-small:calc(var(--global-space--list-indent)/4);--indent-medium:calc(var(--global-space--list-indent)/2);--indent-large:var(--global-space--list-indent);border:var(--global-border--normal);width:-moz-fit-content;width:fit-content}nav.c-nav--boxed :is(ul,ol){margin:0}nav.c-nav--boxed ul{list-style-type:none;padding-left:var(--indent-medium);padding-right:var(--indent-large)}@media (min-width:992px){nav.c-nav--boxed{padding-block:var(--indent-medium)}nav.c-nav--boxed ol{padding-left:var(--indent-large);padding-right:calc(var(--indent-large) - var(--link-padding))}}@media (max-width:991px){nav.c-nav--boxed{padding-block:var(--indent-small)}nav.c-nav--boxed ol{padding-left:calc(var(--indent-medium) - var(--link-padding));padding-right:calc(var(--indent-large) - var(--link-padding))}}nav.c-nav--boxed.c-nav--no-list{padding-left:var(--indent-medium);padding-right:var(--indent-large)}nav.c-nav{--space-between-inline-items:0.5em}nav.c-nav a{display:inline-block;padding-inline:var(--link-padding)}nav.c-nav--no-list{display:flex;flex-wrap:wrap}nav.c-nav--no-list>a{margin-right:var(--space-between-inline-items)}@media (max-width:991px){nav.c-nav a{line-height:2.5}nav.c-nav :is(ul,ol){display:flex;flex-wrap:wrap;list-style-position:inside}nav.c-nav :is(ul,ol):not(.c-nav--boxed :is(ul,ol)){padding-left:unset}nav.c-nav :is(ul,ol) li{margin-right:var(--space-between-inline-items)}nav.c-nav ul{list-style-type:none}}.c-footer{--line-height:1.5;--min-line-count:2;background-color:var(--global-color-primary--xx-dark);box-sizing:content-box;color:var(--global-color-primary--xx-light);display:flex;flex-direction:column;font-size:12px;justify-content:center;min-height:calc(var(--line-height)*var(--min-line-count)*1em);padding-bottom:20px;padding-top:20px;text-align:center}@media only screen and (max-width:640px){.c-footer{padding-left:5%;padding-right:5%}}@media only screen and (min-width:641px) and (max-width:767px){.c-footer{padding-left:7.5%;padding-right:7.5%}}@media only screen and (min-width:768px) and (max-width:991px){.c-footer{padding-left:10%;padding-right:10%}}@media only screen and (min-width:992px) and (max-width:1199px){.c-footer{padding-left:12.5%;padding-right:12.5%}}@media only screen and (min-width:1200px){.c-footer{padding-left:15%;padding-right:15%}}.c-recognition{font-size:var(--global-font-size--small)}.c-recognition{overflow:auto;padding:0 2.14em}.c-recognition h3{margin-top:.7em}.c-recognition>p:last-child{margin-bottom:1.4em}.c-recognition--style-dark{background-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-light)}.c-recognition--style-dark a{color:var(--global-color-link-on-dark--normal)}.c-recognition--style-dark h1,.c-recognition--style-dark h2,.c-recognition--style-dark h3,.c-recognition--style-dark h4,.c-recognition--style-dark h5,.c-recognition--style-dark h6{color:var(--global-color-accent--normal)}.c-recognition--style-light{background-color:var(--global-color-primary--xx-light);border-color:var(--global-color-primary--xx-dark);border-style:solid;border-width:var(--global-border-width--normal) 0;color:var(--global-color-primary--dark)}.c-recognition--style-light a{color:var(--global-color-link-on-light--normal)}.c-recognition--style-light h1,.c-recognition--style-light h2,.c-recognition--style-light h3,.c-recognition--style-light h4,.c-recognition--style-light h5,.c-recognition--style-light h6{color:var(--global-color-primary--xx-dark)}.c-see-all-link{display:inline-block;font-size:1.2rem;font-weight:var(--bold);margin-bottom:-1em;max-width:100%;padding-bottom:1em;padding-right:1em;padding-top:1em}.c-see-all-link__icon{display:inline-block;font-size:1.167em;margin-right:.75em;vertical-align:text-bottom}.c-see-all-link__text{font-size:1em}@media (min-width:1680px){.container{max-width:var(--global-max-width--x-wide)}}@media (min-width:1920px){.container{max-width:var(--global-max-width--xx-wide)}}.figure>a>img,.figure>img{margin-bottom:20px}.figure-caption{border-top:var(--global-border-width--normal) solid var(--global-color-primary--normal);color:var(--global-color-primary--dark);font-size:var(--global-font-size--medium);padding-top:12px}.modal-body,.modal-content,.modal-footer,.modal-header{border-radius:0}.modal-body,.modal-content,.modal-header{border:none}.modal-footer{border-bottom:none;border-left:none;border-right:none}.modal-header{background-color:var(--global-color-primary--x-light);padding:1.35rem 1.75rem}.modal-title{color:var(--global-color-primary--xx-dark);font-size:1.2rem;font-weight:400}.modal-header .close{color:var(--global-color-primary--x-dark);opacity:1}.modal-header .close:not(:disabled):not(.disabled):focus,.modal-header .close:not(:disabled):not(.disabled):hover{color:var(--global-color-primary--xx-dark);opacity:1}.modal-header .close span{font-family:Cortal-Icons!important;font-size:1.5rem}.modal-header.has-MuiTabs{border-bottom:1px solid #afafaf;flex-direction:row;height:63.5px;padding:5px;position:relative}.modal-header.has-MuiTabs .close{transform:translate(-25%,25%)}.button-wrapper button[type=submit],.c-button,.form-button{--min-width:75px;--mid-width:110px;--max-width:130px;border-style:solid;border-width:var(--global-border-width--normal);display:inline-block}.button-wrapper button[type=submit]:not(.c-button--as-link),.c-button:not(.c-button--as-link),.form-button:not(.c-button--as-link){font-weight:var(--medium)}a.c-button{text-align:center;text-decoration:none}a.c-button--is-busy{cursor:default}.button-wrapper button[type=submit]:not(:disabled,:where(a[disabled])),.c-button:not(:disabled,:where(a[disabled])),.form-button:not(:disabled,:where(a[disabled])){cursor:pointer}.button-wrapper button[type=submit]:disabled:not(.c-button--is-busy),.button-wrapper button[type=submit]:where(a[disabled]):not(.c-button--is-busy),.c-button:disabled:not(.c-button--is-busy),.c-button:where(a[disabled]):not(.c-button--is-busy),.form-button:disabled:not(.c-button--is-busy),.form-button:where(a[disabled]):not(.c-button--is-busy){border-color:var(--global-color-primary--dark);color:var(--global-color-primary--dark);pointer-events:none}.button-wrapper button[type=submit]:disabled:not(.c-button--is-busy,.c-button--as-link),.button-wrapper button[type=submit]:where(a[disabled]):not(.c-button--is-busy,.c-button--as-link),.c-button:disabled:not(.c-button--is-busy,.c-button--as-link),.c-button:where(a[disabled]):not(.c-button--is-busy,.c-button--as-link),.form-button:disabled:not(.c-button--is-busy,.c-button--as-link),.form-button:where(a[disabled]):not(.c-button--is-busy,.c-button--as-link){background-color:var(--global-color-primary--xx-light)}.button-wrapper button[type=submit],.c-button--is-active,.c-button--primary,.c-button--secondary,.c-button--tertiary,.form-button{max-width:var(--max-width);min-width:var(--min-width);padding:6px 18px}.button-wrapper button[type=submit]:hover,.c-button--primary:hover,.form-button:hover{background-color:var(--global-color-accent--dark);border-color:var(--global-color-accent--dark);color:var(--global-color-primary--xx-light)}.button-wrapper button[type=submit]:active:not(.c-button--is-busy),.c-button--primary:active:not(.c-button--is-busy),.form-button:active:not(.c-button--is-busy){background-color:var(--global-color-accent--x-dark);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-light);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.button-wrapper button[type=submit]:focus:not(:active,.c-button--is-busy),.c-button--primary:focus:not(:active,.c-button--is-busy),.form-button:focus:not(:active,.c-button--is-busy){background-color:var(--global-color-accent--normal);border-color:var(--global-color-primary--xx-light);color:var(--global-color-primary--xx-light);outline:var(--global-border-width--normal) solid var(--global-color-accent--light)}.button-wrapper button[type=submit].c-button--is-busy,.button-wrapper button[type=submit]:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])),.c-button--primary.c-button--is-busy,.c-button--primary:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])),.form-button.c-button--is-busy,.form-button:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-accent--normal);border-color:var(--global-color-accent--normal);color:var(--global-color-primary--xx-light)}.c-button--secondary:hover{background-color:var(--global-color-accent--weak);border-color:var(--global-color-accent--normal);color:var(--global-color-primary--xx-dark)}.c-button--secondary:active:not(.c-button--is-busy){background-color:var(--global-color-accent--x-light);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.c-button--secondary:focus:not(:active,.c-button--is-busy){background-color:var(--global-color-accent--weak);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--thick) solid var(--global-color-accent--light)}.c-button--secondary.c-button--is-busy,.c-button--secondary:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-primary--x-light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark)}.c-button.c-button--secondary:disabled,.c-button.c-button--secondary:where(a[disabled]),/* for specificity to override */,/* for specificity to override */{background-color:var(--global-color-primary--x-light)}.c-button--tertiary:hover{background-color:var(--global-color-primary--light);border-color:var(--global-color-accent--dark);color:var(--global-color-primary--xx-dark)}.c-button--tertiary:active:not(.c-button--is-busy){background-color:var(--global-color-accent--x-light);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.c-button--tertiary:focus:not(:active,.c-button--is-busy){background-color:var(--global-color-primary--light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--thick) solid var(--global-color-accent--light)}.c-button--tertiary.c-button--is-busy,.c-button--tertiary:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-primary--xx-light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark)}.c-button--is-active:hover{background-color:var(--global-color-accent--alt);border-color:var(--global-color-accent--dark);color:var(--global-color-primary--xx-dark)}.c-button--is-active:active{background-color:var(--global-color-accent--x-light);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.c-button--is-active:focus:not(:active){background-color:var(--global-color-accent--alt);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--thick) solid var(--global-color-accent--light)}.c-button--is-active.c-button--is-busy,.c-button--is-active:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-accent--x-light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark)}.c-button--as-link{background:unset;border:unset;font-family:inherit;font-size:inherit;padding-inline:unset}.c-button--is-busy{opacity:.5}.c-button--is-busy .c-button__text{opacity:.3}.button-wrapper button[type=submit]:not(.c-button--width-short,.c-button--width-medium,.c-button--width-long,.c-button--size-small,.c-button--as-link),.c-button:not(.c-button--width-short,.c-button--width-medium,.c-button--width-long,.c-button--size-small,.c-button--as-link),.form-button:not(.c-button--width-short,.c-button--width-medium,.c-button--width-long,.c-button--size-small,.c-button--as-link){--max-width:auto;width:auto}.c-button--width-short{width:var(--min-width)}.c-button--width-medium{width:var(--mid-width)}.c-button--width-long{width:var(--max-width)}.c-button--size-small{line-height:1;min-width:0;padding:4px 9px}.button-wrapper button[type=submit]>*,.c-button>*,.form-button>*{vertical-align:middle}.c-button__icon--before{margin-right:.5em}.c-button__icon--after{margin-left:.5em}.button-wrapper button[type=submit]:not(.c-button--as-link),.c-button:not(.c-button--as-link),.form-button:not(.c-button--as-link){font-size:var(--global-font-size--small)}.cms-ready{--cms-toolbar-height:46px}.cms-ready :target{scroll-margin-top:var(--cms-toolbar-height)}.cms-ready .position-sticky.fixed-top,.cms-ready .sticky-top{top:var(--cms-toolbar-height)}.field-wrapper.checkboxselectmultiple.required>label:after{border:var(--global-border--thick);display:block;font-size:var(--global-font-size--small);margin-top:.5em;padding:15px 20px}html[class*=cms-structure-mode-] .field-wrapper.checkboxselectmultiple.required>label:after{background-color:var(--global-color-danger--weak);border-color:var(--global-color-danger--normal);color:var(--global-color-danger--dark);content:"A multi checkbox field that is required is not well implemented. Do not require this field or replace it with multiple required Yes/No radio fields."}html:not([class*=cms-structure-mode-]) .field-wrapper.checkboxselectmultiple.required>label:after{background-color:var(--global-color-warning--weak);border-color:var(--global-color-warning--normal);color:var(--global-color-warning--dark);content:"This field is not well implemented. Select all boxes to bypass the error with this field."}.description{margin-block:25px}.help-text{font-size:var(--global-font-size--small);font-style:italic}:not(ul,label)+.help-text{margin-top:.3em}.help-text>:not(details,a,samp){font-style:normal}.field-wrapper{margin-bottom:2rem}.field-wrapper:not(.checkboxinput){display:flex;flex-direction:column}.field-wrapper:not(.checkboxinput)>.field-errors{order:1}.field-wrapper.checkboxinput{align-items:center;-moz-column-gap:.5em;column-gap:.5em;display:inline-grid;grid-template-areas:"error _____" "input label" "notes notes";grid-template-columns:min-content auto}.field-wrapper.checkboxinput .field-errors{grid-area:error}.field-wrapper.checkboxinput input{grid-area:input}.field-wrapper.checkboxinput label{grid-area:label}.field-wrapper.checkboxinput .help-text{grid-area:notes}.field-wrapper.checkboxinput label{margin-bottom:0}ul.checkboxselectmultiple label,ul.radioselect label{align-items:center;display:flex;gap:.5em}ul.checkboxselectmultiple li:last-child label,ul.radioselect li:last-child label{margin-bottom:0}.field-wrapper.required>label{font-weight:var(--bold)}.field-wrapper.required>label .asterisk{font-weight:var(--regular)}.field-wrapper.required:has(label .asterisk) label:has(sub,sup){align-items:center;display:flex}.field-wrapper .asterisk{margin-left:.5em}.field-wrapper.required .asterisk{color:var(--global-color-danger--dark)}.field-wrapper:not(.required) .asterisk{color:var(--global-color-warning--dark)}.field-wrapper .asterisk{display:inline-block;line-height:0;visibility:hidden;width:0}.field-wrapper .asterisk:after{line-height:normal;visibility:visible}.field-wrapper.required .asterisk:after{content:"(required)"}.field-wrapper:not(.required) .asterisk:after{content:"(important)"}.field-errors{font-size:var(--global-font-size--small)}.field-errors ul{margin-bottom:0;margin-top:1rem}ul.checkboxselectmultiple,ul.radioselect{list-style:none;padding-left:0}.button-wrapper{margin-top:35px}span.has-svg{display:inline-block}span.has-svg>svg{height:100%;width:100%}.align-left,.align-right{margin-bottom:var(--global-space--grid-gap)}.align-right{float:right;margin-left:var(--global-space--grid-gap)}.align-left{float:left;margin-right:var(--global-space--grid-gap)}.align-center{display:block;margin-inline:auto}.align-right+:not(img){clear:right}.align-left+:not(img){clear:left}nav.s-breadcrumbs{font-size:var(--global-font-size--x-small);padding-top:15px;text-transform:uppercase}nav.s-breadcrumbs ol{font-weight:var(--global-font-weight--medium);list-style:none;margin-bottom:unset;padding-left:unset}nav.s-breadcrumbs ol li,ol.s-breadcrumbs li{display:inline-block}nav.s-breadcrumbs ol li+li:before,ol.s-breadcrumbs li+li:before{content:" > "}nav.s-breadcrumbs ol li:last-child span{font-weight:var(--bold)}.s-footer>p:last-of-type{margin:0}.s-footer a{color:var(--global-color-primary--light)}.s-blockquote{margin-bottom:1.25em;margin-top:1.25em}.s-blockquote blockquote{font-size:1.125em;font-style:italic;margin-bottom:0}.s-blockquote blockquote p{margin:0;white-space:pre-wrap}.s-blockquote blockquote p:before{content:"“"}.s-blockquote blockquote p:after{content:"”"}.s-blockquote figcaption{font-size:1em;margin-top:.3em}.s-blockquote figcaption:before{content:"— "}.s-blockquote cite{font-style:normal}.u-mailto-text-replace[data-user][data-domain]{font-size:0;visibility:hidden}.u-mailto-text-replace[data-user][data-domain]:before{content:attr(data-user) "@" attr(data-domain);display:inline;font-size:medium;visibility:visible}.s-affixed-input-wrapper:not(.checkboxinput,.radio,.select,.checkboxselectmultiple,.textarea){align-items:start;display:grid;grid-template-areas:"label label" var(--input-row,"input input") "help help" "error error";grid-template-columns:auto 1fr}@supports selector(:has(*)){.s-affixed-input-wrapper:has(.s-affixed-input-wrapper__prefix){--input-row:"prefix input"}.s-affixed-input-wrapper:has(.s-affixed-input-wrapper__suffix){--input-row:"input suffix"}}@supports not selector(:has(*)){.s-affixed-input-wrapper--prefix{--input-row:"prefix input"}.s-affixed-input-wrapper--suffix{--input-row:"input suffix"}}.s-affixed-input-wrapper label{grid-area:label}.s-affixed-input-wrapper input{grid-area:input}.s-affixed-input-wrapper__prefix{grid-area:prefix}.s-affixed-input-wrapper__suffix{grid-area:suffix}.s-affixed-input-wrapper .help-text{grid-area:help}.s-affixed-input-wrapper .field-errors{grid-area:error}.s-affixed-input-wrapper{--width:1em;--padding-vert:5px;--padding-horz:10px}.s-affixed-input-wrapper__prefix,.s-affixed-input-wrapper__suffix{box-sizing:content-box;display:inline-block;font-family:var(--global-font-family--sans--portal);padding:var(--padding-vert) var(--padding-horz);pointer-events:none;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--width)}.s-affixed-input-wrapper__prefix{left:var(--global-border-width--normal);margin-right:calc(var(--width)*-1 - var(--padding-horz)*2);position:relative;top:var(--global-border-width--normal)}.s-affixed-input-wrapper__suffix{margin-left:calc(var(--width)*-1 - var(--padding-horz)*2);position:relative;right:var(--global-border-width--normal);top:var(--global-border-width--normal)}.s-affixed-input-wrapper__prefix+input{text-indent:calc(var(--width) + var(--padding-horz))} +/*! @tacc/core-cms v3.10.1 | MIT | github.com/TACC/Core-CMS *//*! EDITS: TACC/Core-CMS#660 */@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap");:root{--header-text-color:var(--global-color-primary--xx-light);--header-bkgd-color:var(--global-color-primary--xx-dark);--header-minor-border-color:var(--global-color-primary--normal);--header-major-border-color:var(--header-bkgd-color);--header-search-brdr-color:var(--global-color-primary--dark);--header-search-bkgd-color:#313131;--menu-toggle-icon:none}:root{--global-border-width--normal:1px;--global-border--normal:var(--global-border-width--normal) solid var(--global-color-primary--normal);--global-border-width--thick:2px;--global-border--thick:var(--global-border-width--thick) solid var(--global-color-primary--normal);--global-border-width--x-thick:3px;--global-border--x-thick:var(--global-border-width--x-thick) solid var(--global-color-primary--normal)}:root{--global-max-width--x-narrow:540px;--global-max-width--narrow:720px;--global-max-width--medium:960px;--global-max-width--wide:1140px;--global-max-width--x-wide:1320px;--global-max-width--xx-wide:1580px;--global-max-width--xxx-wide:1800px}:root{--global-space--xx-small:2px;--global-space--x-small:4px;--global-space--small:8px;--global-space--normal:16px;--global-space--large:24px;--global-space--x-large:48px;--global-space--list-indent:40px;--global-space--section-gap:45px;--global-space--grid-gap:15px;--global-space--section-top:12px;--global-space--section-bottom:0;--global-space--section-left:24px;--global-space--section-right:36px;--global-space--section:var(--global-space--section-top) var(--global-space--section-right) var(--global-space--section-bottom) var(--global-space--section-left);--global-space--hr-buffer-above:10px;--global-space--hr-buffer-below:30px}:root{--global-color-primary--xx-light:#fff;--global-color-primary--xx-light-rgb:255,255,255;--global-color-primary--x-light:#f4f4f4;--global-color-primary--x-light-rgb:244,244,244;--global-color-primary--light:#c6c6c6;--global-color-primary--normal:#afafaf;--global-color-primary--dark:#707070;--global-color-primary--x-dark:#484848;--global-color-primary--x-dark-rgb:72,72,72;--global-color-primary--xx-dark:#222;--global-color-primary--xx-dark-rgb:34,34,34;--global-color-accent--x-light:#AAC7FF;--global-color-accent--light:#86aeff;--global-color-accent--normal:#003399;--global-color-accent--dark:#002266;--global-color-accent--x-dark:#001133;--global-color-accent--alt:#cbd4e7;--global-color-accent--weak:#00226640;--global-color-info--dark:var(--global-color-primary--x-dark);--global-color-info--normal:var(--global-color-primary--normal);--global-color-info--light:var(--global-color-primary--x-light);--global-color-success--dark:#237119;--global-color-success--normal:#43d130;--global-color-success--weak:#43d13020;--global-color-success--alt:var(--global-color-warning--normal);--global-color-success--alt-weak:var(--global-color-warning--weak);--global-color-warning--dark:#717411;--global-color-warning--normal:#c7ce1d;--global-color-warning--weak:#c7ce1d20;--global-color-warning--alt:var(--global-color-accent--dark);--global-color-warning--alt-weak:var(--global-color-accent--weak);--global-color-danger--dark:#af1818;--global-color-danger--normal:#f09393;--global-color-danger--weak:#f0939320;--global-color-background--app:var(--global-color-primary--xx-light);--global-color-link-on-light--normal:var(--global-color-accent--normal);--global-color-link-on-dark--normal:var(--global-color-accent--light)}@font-face{font-display:swap;font-family:Benton Sans;font-style:normal;font-weight:400;src:url(/static/site_cms/fonts/BentonSans-Regular.otf) format("opentype")}@font-face{font-display:swap;font-family:Benton Sans;font-style:normal;font-weight:700;src:url(/static/site_cms/fonts/BentonSans-Bold.otf) format("opentype")}@font-face{font-display:swap;font-family:Benton Sans;font-style:normal;font-weight:500;src:url(/static/site_cms/fonts/BentonSans-Medium.otf) format("opentype")}@font-face{font-display:swap;font-family:Benton Sans;font-style:italic;font-weight:500;src:url(/static/site_cms/fonts/BentonSans-MediumItalic.otf) format("opentype")}:root{--global-font-family--sans--cms:"Benton Sans","Roboto",sans-serif;--global-font-family--sans--portal:"Roboto",sans-serif;--global-font-family--serif:Times,sans-serif;--global-font-family--mono:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace;--global-font-size--x-small:1.1rem;--global-font-size--small:1.4rem;--global-font-size--medium:1.6rem;--global-font-size--large:2.0rem;--global-font-size--x-large:2.6rem;--global-font-size--xx-large:3.2rem;--global-font-size--xxx-large:4.1rem;--global-font-weight--regular:400;--global-font-weight--medium:500;--global-font-weight--bold:700;--regular:400;--medium:500;--bold:700}:root{--global-font-family--sans:var(--global-font-family--sans--cms);--global-font-family:var(--global-font-family--sans);--font-family-sans-serif:var(--global-font-family--sans);--font-family-monospace:var(--global-font-family--mono)}html{font-size:62.5%}body,html{height:100%}body{color:var(--global-color-primary--x-dark);font-family:var(--global-font-family--sans--cms);font-size:var(--global-font-size--medium);line-height:1.4;min-width:290px}body>main{margin-bottom:var(--global-space--section-gap)}body>main+footer{position:sticky;top:100vh}h1,h2,h3,h4,h5,h6{color:var(--global-color-primary--xx-dark)}h1,h2,h4,h5,h6{font-weight:var(--bold)}h1{margin-bottom:27px;margin-top:27px}h2{margin-bottom:var(--global-space--normal);margin-top:30px}h1+h2,h1+hr{margin-top:-12px}h1{font-size:var(--global-font-size--xxx-large)}h2{font-size:var(--global-font-size--x-large)}h3,h4,h5,h6{margin-bottom:var(--global-space--normal);margin-top:var(--global-space--normal)}h3{font-size:var(--global-font-size--x-large)}h4{font-size:var(--global-font-size--large)}h5{text-transform:uppercase}h5,h6{font-size:var(--global-font-size--medium)}p{margin-bottom:2rem}dl dl,ol,ul{padding-left:var(--global-space--list-indent)}ol ol,ol ul,ul ol,ul ul{margin:revert}dt{font-weight:400;margin-bottom:.5rem}li:not(td li){line-height:1.6}hr{border-top:1px solid var(--global-color-primary--light);margin-bottom:var(--global-space--hr-buffer-below);margin-top:var(--global-space--hr-buffer-above)}code,kbd,pre,samp,var{font-family:var(--global-font-family--mono)}code kbd{display:inline-block;font-size:inherit;margin-left:.2rem;margin-right:.2rem;padding:.1rem .2rem}code,pre>samp{color:unset}:not(pre)>code{display:inline-block;padding:var(--global-space--xx-small) var(--global-space--x-small)}pre>code,pre>samp{display:inline-block;padding:var(--global-space--x-small) var(--global-space--small)}pre[style]>code,pre[style]>samp{min-width:100%}pre samp{opacity:.75;text-decoration:none}pre code u{opacity:.5;text-decoration:none}details{margin-bottom:1rem;margin-top:0}input,label,select,textarea{font-family:var(--global-font-family--sans--portal)}label{font-size:var(--global-font-size--small);line-height:normal;margin-bottom:.75em}li>label:only-child{margin-bottom:unset}:not(input[type=checkbox])+label{display:block}fieldset:not(:last-child){margin-bottom:3.5rem}input,select,textarea{border:var(--global-border--normal)}::-moz-placeholder{color:var(--global-color-primary--dark)}::placeholder{color:var(--global-color-primary--dark)}input[type=date],input[type=time]{font-family:var(--global-font-family--mono)}input:not([type=time],[type=date],[type=checkbox],[type=radio]),select,textarea{max-width:50ch}input:where([type=time],[type=date],[type=checkbox],[type=radio]){width:-moz-min-content;width:min-content}@media (pointer:coarse){input,select,textarea{padding:12px}}@media (pointer:fine),(pointer:none){input,select,textarea{padding:5px 10px}}.c-button--as-link,.s-irregular-links .c-button--as-link,.s-irregular-links a,.x-link,.x-link--irregular,a{color:var(--global-color-link-on-light--normal);text-decoration:none;text-decoration-thickness:var(--global-border-width--normal);text-underline-offset:.2em}.c-button--as-link:where(:not(:disabled,:where(a[disabled]))):hover,.s-irregular-links .c-button--as-link:hover,.s-irregular-links a:hover,.x-link--hover,.x-link--irregular--hover,a:hover{color:var(--global-color-link-on-light--normal);text-decoration-line:underline;text-decoration-style:solid;text-decoration-thickness:var(--global-border-width--normal)}.c-button--as-link:active,.s-irregular-links .c-button--as-link:active,.s-irregular-links a:active,.x-link--active,.x-link--irregular--active,a:active{text-decoration-line:underline;text-decoration-style:dotted}.s-irregular-links .c-button--as-link,.s-irregular-links a,.x-link--irregular{text-decoration-line:underline}.s-irregular-links .c-button--as-link:hover,.s-irregular-links a:hover,.x-link--irregular--hover{text-decoration-style:dashed}.s-irregular-links .c-button--as-link:active,.s-irregular-links a:active,.x-link--irregular--active{text-decoration-style:dotted}.x-truncate--many-lines,table p{--lines:2;-webkit-box-orient:vertical;-webkit-line-clamp:var(--lines);display:-webkit-box;overflow:hidden}.x-untruncate--many-lines{-webkit-line-clamp:inherit;overflow:visible}.button-wrapper button[type=submit],.c-button,.c-data-list--should-truncate-values .c-data-list__value,.c-data-list__key,.c-see-all-link,.form-button,.modal-title,.x-truncate--one-line{overflow:hidden;text-overflow:var(--text-overflow,ellipsis);white-space:nowrap}.x-untruncate--one-line{overflow:visible;white-space:normal}table{border-collapse:separate;border-spacing:0;font-family:var(--global-font-family--sans--portal);font-size:var(--global-font-size--small)}thead tr :is(td,th),tr:not(:last-of-type)>:is(td,th){border-bottom:var(--global-border--normal)}tr:nth-child(odd) :is(th,td){background:var(--global-color-background--app)}tr:nth-child(2n) :is(th,td){background:var(--global-color-primary--x-light)}:is(td,th){color:var(--global-color-primary--dark);padding-block:8px;padding-inline:16px;vertical-align:top}:is(td,th){line-height:var(--global-font-size--medium)}:is(th,td):first-child{border-right:var(--global-border-width--normal) solid var(--global-color-primary--light);left:0;position:sticky}th{color:var(--global-color-primary--x-dark);text-align:inherit}thead>tr>th{font-weight:var(--bold)}tbody>tr>th{font-weight:var(--normal)}caption{font-size:var(--global-font-size--small);text-align:unset}td ul{-webkit-padding-start:0;list-style:none;margin-block:0;padding-inline-start:0}td li:not(:last-of-type){margin-bottom:.5em}td button{font-size:inherit}table p{margin-top:0}table p:last-child{margin-bottom:0}@supports selector(:has(table)){table:has(table) :is(td,th){white-space:nowrap}table:has(table) tr:nth-child(2n) :is(th,td){background:var(--global-color-background--app)}td:has(table) tr:nth-child(2n) :is(th,td){background:var(--global-color-primary--x-light)}td:has(table){padding:0}}@supports not selector(:has(table)){table.has-table :is(td,th){white-space:nowrap}table.has-table tr:nth-child(2n) :is(th,td){background:var(--global-color-background--app)}td.has-table tr:nth-child(2n) :is(th,td){background:var(--global-color-primary--x-light)}td.has-table{padding:0}}tr table{--offset:-33px;margin-bottom:var(--offset);transform:translateY(var(--offset))}tr:first-of-type thead{background:var(--global-color-background--app)}tr:not(:first-of-type) thead{visibility:hidden}td:not(:first-child) td:first-child,td:not(:first-child) th:first-child{-webkit-padding-start:8px;padding-inline-start:8px}td:not(:last-child) td:last-child,td:not(:last-child) th:last-child{-webkit-padding-end:8px;padding-inline-end:8px}.o-grid--col-auto-count{grid-template-columns:repeat(var(--count),auto)}.o-grid--col-min-width{grid-template-columns:repeat(auto-fit,minmax(var(--width),1fr))}.o-grid{grid-auto-rows:1fr}.o-grid--center-align{align-items:center;justify-items:center}.o-grid{--gap:var(--global-space--grid-gap,15px);display:grid;gap:var(--gap)}.o-grid img{max-height:100%;max-width:100%}.o-grid>*{overflow:hidden}@media (max-width:575px){.o-grid--col-auto-count{--count:1}}@media (min-width:576px) and (max-width:767px){.o-grid--col-auto-count{--count:2}}@media (min-width:768px) and (max-width:991px){.o-grid--col-auto-count{--count:3}}@media (min-width:992px) and (max-width:1199px){.o-grid--col-auto-count{--count:4}}@media (min-width:1200px) and (max-width:1399px){.o-grid--col-auto-count{--count:5}}@media (min-width:1400px) and (max-width:1679px){.o-grid--col-auto-count{--count:6}}@media (min-width:1680px) and (max-width:1919px){.o-grid--col-auto-count{--count:7}}@media (min-width:1920px) and (max-width:2399px){.o-grid--col-auto-count{--count:8}}@media (min-width:2400px){.o-grid--col-auto-count{--count:9}}.o-grid--col-min-width{--width:250px}.o-grid--col-min-width>:not(img){max-height:100%;max-width:100%}.o-grid--image-fill>:is(a,figure):not(img){height:100%;width:100%}.o-grid--image-fill>a>img:only-child,.o-grid--image-fill>figure>img,.o-grid--image-fill>img{height:100%;-o-object-fit:cover;object-fit:cover;width:100%}.o-grid--image-fill>figure:not([class]),.o-grid--image-fill>figure[class*=cms-plugin],.o-grid--image-fill>figure[class=""]{display:flex;flex-direction:column}.o-grid--image-fill>figure:not([class])>img,.o-grid--image-fill>figure[class*=cms-plugin]>img,.o-grid--image-fill>figure[class=""]>img{flex-grow:1;min-height:0}.o-float-content--left,.o-float-content--right{--buffer:calc(var(--global-space--grid-gap)*2)}@media only screen and (min-width:992px){.o-float-content--right{float:right;margin-left:var(--buffer)}.o-float-content--right+.o-float-content--right{clear:right}.o-float-content--left{float:left;margin-right:var(--buffer)}.o-float-content--left+.o-float-content--left{clear:left}.figure:is(.o-float-content--left,.o-float-content--right) .figure-caption{padding-right:125px}}@media only screen and (min-width:992px) and (max-width:2399px){.o-float-content--left,.o-float-content--right{max-width:560px}}.o-offset-content--left,.o-offset-content--right{--offset-distance:min(15vw,410px);--buffer:calc(var(--global-space--grid-gap)*2)}@media only screen and (min-width:992px){.o-offset-content--right{float:right;margin-left:var(--buffer)}.o-offset-content--right+.o-offset-content--right{clear:right}.o-offset-content--left{float:left;margin-right:var(--buffer)}.o-offset-content--left+.o-offset-content--left{clear:left}.figure:is(.o-offset-content--left,.o-offset-content--right) .figure-caption{padding-right:125px}}@media only screen and (min-width:992px) and (max-width:2399px){.o-offset-content--left,.o-offset-content--right{max-width:560px}.o-offset-content--right{margin-right:calc(var(--offset-distance)*-1)}.o-offset-content--left{margin-left:calc(var(--offset-distance)*-1)}}.o-section--layout-a,.o-section--layout-b,.o-section--layout-c,.o-section--layout-d,.x-layout--a,.x-layout--b,.x-layout--c,.x-layout--d{display:grid}@media (max-width:991px){.o-section--layout-a,.x-layout--a{grid-template-columns:repeat(1,minmax(0,1fr))}}@media (min-width:992px){.o-section--layout-a,.x-layout--a{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width:991px){.o-section--layout-b,.x-layout--b{grid-template-columns:minmax(0,1fr)}}@media (min-width:992px){.o-section--layout-b,.x-layout--b{grid-template-columns:minmax(0,2fr) minmax(0,1fr)}}@media (max-width:991px){.o-section--layout-c,.x-layout--c{grid-template-columns:minmax(0,1fr)}}@media (min-width:992px){.o-section--layout-c,.x-layout--c{grid-template-columns:minmax(0,1fr) minmax(0,2fr)}}@media (max-width:575px){.o-section--layout-d,.x-layout--d{grid-template-columns:repeat(1,minmax(0,1fr))}}@media (min-width:576px) and (max-width:767px),(min-width:768px) and (max-width:991px){.o-section--layout-d,.x-layout--d{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:992px){.o-section--layout-d,.x-layout--d{grid-template-columns:repeat(3,minmax(0,1fr))}}.x-layout--e{display:flex;flex-direction:column}.o-section--style-dark+.o-section--style-dark.container,.o-section--style-light+.o-section--style-light.container{--fb--line-width:0px;--fb--line-color:transparent;--fb--inset-width:0px;--fb--inset-color:transparent;--fb--start:inset calc(var(--fb--inset-width)*1) 0 var(--fb--inset-color);--fb--end:inset calc(var(--fb--inset-width)*-1) 0 var(--fb--inset-color);--fb:var(--fb--start),var(--fb--end),var(--fb--line);box-shadow:var(--fb--shadow-above,0 0 transparent),var(--fb),var(--fb--shadow-below,0 0 transparent)}.o-section--style-dark+.o-section--style-dark.container,.o-section--style-light+.o-section--style-light.container{--fb--line:inset 0 calc(var(--fb--line-width)*1) var(--fb--line-color)}.o-section{--padding-block:var(--global-space--section-gap);padding-block:var(--padding-block)}.o-section .o-section{--hoz-space:1em;margin-inline:calc(var(--hoz-space)*-1);padding-block:1em;padding-inline:var(--hoz-space)}.o-section--banner{overflow:hidden}.o-section--banner [class*=o-section--layout]{gap:0}.o-section--banner .container{padding-inline:0}.o-section--banner.o-section{padding-block:0}.o-section--intro .u-empty,.o-section--intro>:empty:not(img){display:none}.o-section--style-light{--color--text:var(--global-color-primary--dark);--color--text-strong:var(--global-color-primary--xx-dark);--color--bkgd:var(--global-color-primary--xx-light);--color--line:var(--global-color-primary--normal);--color--link:var(--global-color-link-on-light--normal)}.o-section--style-muted{--color--text:var(--global-color-primary--x-dark);--color--text-strong:var(--global-color-primary--xx-dark);--color--bkgd:var(--global-color-primary--x-light);--color--line:var(--global-color-primary--dark);--color--link:var(--global-color-link-on-light--normal)}.o-section--style-dark{--color--text:var(--global-color-primary--x-light);--color--text-strong:var(--global-color-primary--xx-light);--color--bkgd:var(--global-color-primary--xx-dark);--color--line:var(--global-color-primary--xx-light);--color--link:var(--global-color-link-on-dark--normal)}[class*=o-section--style]{--line-width:var(--global-border-width--normal);--box-shadow--fake-bkgd:50vw 0 var(--color--bkgd),-50vw 0 var(--color--bkgd);background-color:var(--color--bkgd);box-shadow:var(--box-shadow--fake-bkgd);color:var(--color--text)}[class*=o-section--style] [class*=o-section--style]{box-shadow:none}.o-section--style-dark+.o-section--style-dark:not(.container),.o-section--style-light+.o-section--style-light:not(.container){border-top:var(--line-width) solid var(--color--line)}.o-section--style-muted{border-bottom:var(--line-width) solid var(--color--line);border-top:var(--line-width) solid var(--color--line)}.o-section--style-muted{--box-shadow--fake-bkgd:50vw 0 0 calc(var(--line-width)*-1) var(--color--bkgd),-50vw 0 0 calc(var(--line-width)*-1) var(--color--bkgd),33vw 0 var(--color--line),-33vw 0 var(--color--line),33vw 0px var(--color--line),-33vw 0px var(--color--line)}.o-section--style-dark+.o-section--style-dark.container,.o-section--style-light+.o-section--style-light.container{--fb--line-width:var(--global-border-width--normal);--fb--line-color:var(--color--line);--fb--inset-width:var(--global-space--grid-gap);--fb--inset-color:var(--color--bkgd);--fb--shadow-below:var(--box-shadow--fake-bkgd)}[class*=o-section--style] a{color:var(--color--link)}[class*=o-section--style] :is(h1,h2,h3,h4,h5,h6){color:var(--color--text-strong)}.o-section--layout-a,.o-section--layout-b,.o-section--layout-c,.o-section--layout-d{--gap:3.0rem;gap:var(--gap)}[class*=o-section--style].o-section--banner+[class*=o-section--style]{box-shadow:var(--box-shadow--fake-bkgd)}.o-section--banner .o-section__banner-image{left:50%;min-height:100%;-o-object-fit:cover;object-fit:cover;position:absolute;top:50%;transform:translate(-50%,-50%);width:100vw;z-index:1}.o-section--banner .o-section__banner-overlay{position:relative;z-index:2}main>.container.o-section--style-dark:last-of-type,main>.container.o-section--style-light:last-of-type,main>.container>.o-section--style-dark:last-of-type,main>.container>.o-section--style-light:last-of-type{margin-bottom:calc(var(--padding-block)*-1)}.x-article-link-stretch{height:100%;left:0;overflow:hidden;position:absolute;top:0;width:100%}.x-article-link-stretch--gapless{left:-15px;width:calc(100% + 30px)}.x-article-link-hover,a.c-callout:hover,a.c-card--frontera-about-page:hover{--outline-offset:1em;outline:1px solid var(--global-color-accent--normal);outline-offset:var(--outline-offset)}.x-article-link-hover--gapless{--outline-offset:0}a.c-callout:active,a.c-card--frontera-about-page:active{outline:1px dotted var(--global-color-accent--normal)}.c-card--frontera-about-page{border-bottom:var(--global-border-width--normal) solid var(--global-color-primary--dark);margin-bottom:4.6rem;width:-moz-fit-content;width:fit-content}a.c-card--frontera-about-page{display:inline-block;text-decoration:none}.c-card--frontera-about-page img+h3{margin-top:1.6rem}.c-card--frontera-about-page img~:last-child{margin-bottom:1.25rem}.c-card--frontera-about-page figure{margin:0}.c-card--frontera-about-page figcaption{color:var(--global-color-primary--xx-dark);font-size:var(--global-font-size--x-large);font-weight:var(--bold);margin-bottom:1.25rem;margin-top:1.6rem}.c-callout{--figure-width--no-units:310;--figure-height--no-units:130;display:grid}.c-callout>:is(img,figure){grid-area:figure}.c-callout>:is(h1,h2,h3,h4,h5,h6){grid-area:title}.c-callout>p{grid-area:desc}.c-callout>p{margin-top:0}.c-callout>figure>img,.c-callout>img{aspect-ratio:var(--figure-width--no-units) /var(--figure-height--no-units);-o-object-fit:cover;object-fit:cover}.c-callout>figure{width:-moz-min-content;width:min-content}@media only screen and (min-width:768px){.c-callout{grid-template-areas:"figure title" "figure desc";grid-template-columns:min-content auto;grid-template-rows:auto min-content;padding:20px;text-align:left}.c-callout>figure{margin:0}.c-callout>:is(img,figure){margin-right:40px}.c-callout>figure>img,.c-callout>img{max-width:-moz-fit-content;max-width:fit-content;width:calc(var(--figure-width--no-units)*1px)}.c-callout>img{min-height:100%}}@media only screen and (max-width:767px){.c-callout{grid-template-areas:"figure" "title" "desc";padding:20px 40px;text-align:center}.c-callout>figure{margin:0}.c-callout>:is(img,figure){margin-bottom:20px}.c-callout>figure>img,.c-callout>img{height:calc(var(--figure-height--no-units)*1px);max-height:-moz-fit-content;max-height:fit-content}.c-callout>img{min-width:100%}}.c-callout>:is(img,figure){place-self:center}.c-callout>p{padding-right:1%}.c-callout{background-color:var(--global-color-link-on-light--normal)}.c-callout>:is(h1,h2,h3,h4,h5,h6){border-bottom:1px solid var(--global-color-primary--xx-light);font-size:var(--global-font-size--x-large);font-weight:var(--medium);margin-bottom:12px;margin-top:0;padding-bottom:12px}.c-callout>:is(h1,h2,h3,h4,h5,h6),[class*=o-section--style] .c-callout>:is(h1,h2,h3,h4,h5,h6){color:var(--global-color-primary--xx-light)}.c-callout>:not(h1,h2,h3,h4,h5,h6){color:var(--global-color-primary--xx-light)}.c-callout>:not(h1,h2,h3,h4,h5,h6,figure){font-size:var(--global-font-size--large);font-weight:var(--medium)}a.c-callout:hover{text-decoration:none}a.c-callout:focus{text-decoration:none}table.c-data-list{border-left:0;border-right:0}@supports(text-overflow:":"){.c-data-list__key:not(th){--text-overflow:":"}}td.c-data-list__value,th.c-data-list__key{padding-block:.5em}.c-data-list__key:not(th):after{content:":";display:inline;padding-right:.25em}th.c-data-list__key{padding-right:.25em}.c-data-list--is-horz{display:flex;flex-direction:row}.c-data-list--is-horz dd.c-data-list__value,dl.c-data-list--is-horz{margin-bottom:0}table.c-data-list--is-horz tbody,table.c-data-list--is-horz tr{display:flex;flex-direction:row;min-width:0}.c-data-list--is-horz:not(table).c-data-list--is-narrow>.c-data-list__key~.c-data-list__key:before{padding-left:.5em;padding-right:.5em}.c-data-list--is-horz:not(table).c-data-list--is-wide>.c-data-list__key~.c-data-list__key:before{padding-left:1em;padding-right:1em}table.c-data-list--is-horz.c-data-list--is-narrow tr:not(:first-child) th.c-data-list__key{padding-left:.5em}table.c-data-list--is-horz.c-data-list--is-narrow td.c-data-list__value{margin-right:.5em}table.c-data-list--is-horz.c-data-list--is-wide tr:not(:first-child) th.c-data-list__key{padding-left:1em}table.c-data-list--is-horz.c-data-list--is-wide td.c-data-list__value{margin-right:1em}table.c-data-list--is-vert{table-layout:fixed;width:100%}.c-data-list--is-vert:not(table)>.c-data-list__value{margin-left:0}.c-data-list--is-vert:not(table).c-data-list--is-narrow>.c-data-list__value,table.c-data-list--is-vert.c-data-list--is-narrow td.c-data-list__value{padding-left:0}.c-data-list--is-vert:not(table).c-data-list--is-wide>.c-data-list__value,table.c-data-list--is-vert.c-data-list--is-wide td.c-data-list__value{padding-left:2.5em}table.c-data-list--is-vert th.c-data-list__key,td.c-data-list__value{border-left:0;border-right:0}table.c-data-list--is-horz td.c-data-list__value,table.c-data-list--is-horz th.c-data-list__key{border-bottom:0;border-top:0}table.c-data-list--is-horz tr:first-child th.c-data-list__key{border-left:0}table.c-data-list--is-horz th.c-data-list__key{border-right:0}.c-data-list--is-horz:not(table)>.c-data-list__key~.c-data-list__key:before{content:"|";display:inline-block}.c-data-list--is-horz:not(table){align-items:baseline}table.c-data-list--is-horz tr{align-items:baseline}table.c-data-list--is-vert td.c-data-list__value,table.c-data-list--is-vert th.c-data-list__key{vertical-align:baseline}nav.c-nav{--link-padding:0.5em}nav.c-nav--boxed{--indent-small:calc(var(--global-space--list-indent)/4);--indent-medium:calc(var(--global-space--list-indent)/2);--indent-large:var(--global-space--list-indent);border:var(--global-border--normal);width:-moz-fit-content;width:fit-content}nav.c-nav--boxed :is(ul,ol){margin:0}nav.c-nav--boxed ul{list-style-type:none;padding-left:var(--indent-medium);padding-right:var(--indent-large)}@media (min-width:992px){nav.c-nav--boxed{padding-block:var(--indent-medium)}nav.c-nav--boxed ol{padding-left:var(--indent-large);padding-right:calc(var(--indent-large) - var(--link-padding))}}@media (max-width:991px){nav.c-nav--boxed{padding-block:var(--indent-small)}nav.c-nav--boxed ol{padding-left:calc(var(--indent-medium) - var(--link-padding));padding-right:calc(var(--indent-large) - var(--link-padding))}}nav.c-nav--boxed.c-nav--no-list{padding-left:var(--indent-medium);padding-right:var(--indent-large)}nav.c-nav{--space-between-inline-items:0.5em}nav.c-nav a{display:inline-block;padding-inline:var(--link-padding)}nav.c-nav--no-list{display:flex;flex-wrap:wrap}nav.c-nav--no-list>a{margin-right:var(--space-between-inline-items)}@media (max-width:991px){nav.c-nav a{line-height:2.5}nav.c-nav :is(ul,ol){display:flex;flex-wrap:wrap;list-style-position:inside}nav.c-nav :is(ul,ol):not(.c-nav--boxed :is(ul,ol)){padding-left:unset}nav.c-nav :is(ul,ol) li{margin-right:var(--space-between-inline-items)}nav.c-nav ul{list-style-type:none}}.c-footer{--line-height:1.5;--min-line-count:2;background-color:var(--global-color-primary--xx-dark);box-sizing:content-box;color:var(--global-color-primary--xx-light);display:flex;flex-direction:column;font-size:12px;justify-content:center;min-height:calc(var(--line-height)*var(--min-line-count)*1em);padding-bottom:20px;padding-top:20px;text-align:center}@media only screen and (max-width:640px){.c-footer{padding-left:5%;padding-right:5%}}@media only screen and (min-width:641px) and (max-width:767px){.c-footer{padding-left:7.5%;padding-right:7.5%}}@media only screen and (min-width:768px) and (max-width:991px){.c-footer{padding-left:10%;padding-right:10%}}@media only screen and (min-width:992px) and (max-width:1199px){.c-footer{padding-left:12.5%;padding-right:12.5%}}@media only screen and (min-width:1200px){.c-footer{padding-left:15%;padding-right:15%}}.c-recognition{font-size:var(--global-font-size--small)}.c-recognition{overflow:auto;padding:0 2.14em}.c-recognition h3{margin-top:.7em}.c-recognition>p:last-child{margin-bottom:1.4em}.c-recognition--style-dark{background-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-light)}.c-recognition--style-dark a{color:var(--global-color-link-on-dark--normal)}.c-recognition--style-dark h1,.c-recognition--style-dark h2,.c-recognition--style-dark h3,.c-recognition--style-dark h4,.c-recognition--style-dark h5,.c-recognition--style-dark h6{color:var(--global-color-accent--normal)}.c-recognition--style-light{background-color:var(--global-color-primary--xx-light);border-color:var(--global-color-primary--xx-dark);border-style:solid;border-width:var(--global-border-width--normal) 0;color:var(--global-color-primary--dark)}.c-recognition--style-light a{color:var(--global-color-link-on-light--normal)}.c-recognition--style-light h1,.c-recognition--style-light h2,.c-recognition--style-light h3,.c-recognition--style-light h4,.c-recognition--style-light h5,.c-recognition--style-light h6{color:var(--global-color-primary--xx-dark)}.c-see-all-link{display:inline-block;font-size:1.2rem;font-weight:var(--bold);margin-bottom:-1em;max-width:100%;padding-bottom:1em;padding-right:1em;padding-top:1em}.c-see-all-link__icon{display:inline-block;font-size:1.167em;margin-right:.75em;vertical-align:text-bottom}.c-see-all-link__text{font-size:1em}@media (min-width:1680px){.container{max-width:var(--global-max-width--x-wide)}}@media (min-width:1920px){.container{max-width:var(--global-max-width--xx-wide)}}.figure>a>img,.figure>img{margin-bottom:20px}.figure-caption{border-top:var(--global-border-width--normal) solid var(--global-color-primary--normal);color:var(--global-color-primary--dark);font-size:var(--global-font-size--medium);padding-top:12px}.modal-body,.modal-content,.modal-footer,.modal-header{border-radius:0}.modal-body,.modal-content,.modal-header{border:none}.modal-footer{border-bottom:none;border-left:none;border-right:none}.modal-header{background-color:var(--global-color-primary--x-light);padding:1.35rem 1.75rem}.modal-title{color:var(--global-color-primary--xx-dark);font-size:1.2rem;font-weight:400}.modal-header .close{color:var(--global-color-primary--x-dark);opacity:1}.modal-header .close:not(:disabled):not(.disabled):focus,.modal-header .close:not(:disabled):not(.disabled):hover{color:var(--global-color-primary--xx-dark);opacity:1}.modal-header .close span{font-family:Cortal-Icons!important;font-size:1.5rem}.modal-header.has-MuiTabs{border-bottom:1px solid #afafaf;flex-direction:row;height:63.5px;padding:5px;position:relative}.modal-header.has-MuiTabs .close{transform:translate(-25%,25%)}.button-wrapper button[type=submit],.c-button,.form-button{--min-width:75px;--mid-width:110px;--max-width:130px;border-style:solid;border-width:var(--global-border-width--normal);display:inline-block}.button-wrapper button[type=submit]:not(.c-button--as-link),.c-button:not(.c-button--as-link),.form-button:not(.c-button--as-link){font-weight:var(--medium)}a.c-button{text-align:center;text-decoration:none}a.c-button--is-busy{cursor:default}.button-wrapper button[type=submit]:not(:disabled,:where(a[disabled])),.c-button:not(:disabled,:where(a[disabled])),.form-button:not(:disabled,:where(a[disabled])){cursor:pointer}.button-wrapper button[type=submit]:disabled:not(.c-button--is-busy),.button-wrapper button[type=submit]:where(a[disabled]):not(.c-button--is-busy),.c-button:disabled:not(.c-button--is-busy),.c-button:where(a[disabled]):not(.c-button--is-busy),.form-button:disabled:not(.c-button--is-busy),.form-button:where(a[disabled]):not(.c-button--is-busy){border-color:var(--global-color-primary--dark);color:var(--global-color-primary--dark);pointer-events:none}.button-wrapper button[type=submit]:disabled:not(.c-button--is-busy,.c-button--as-link),.button-wrapper button[type=submit]:where(a[disabled]):not(.c-button--is-busy,.c-button--as-link),.c-button:disabled:not(.c-button--is-busy,.c-button--as-link),.c-button:where(a[disabled]):not(.c-button--is-busy,.c-button--as-link),.form-button:disabled:not(.c-button--is-busy,.c-button--as-link),.form-button:where(a[disabled]):not(.c-button--is-busy,.c-button--as-link){background-color:var(--global-color-primary--xx-light)}.button-wrapper button[type=submit],.c-button--is-active,.c-button--primary,.c-button--secondary,.c-button--tertiary,.form-button{max-width:var(--max-width);min-width:var(--min-width);padding:6px 18px}.button-wrapper button[type=submit]:hover,.c-button--primary:hover,.form-button:hover{background-color:var(--global-color-accent--dark);border-color:var(--global-color-accent--dark);color:var(--global-color-primary--xx-light)}.button-wrapper button[type=submit]:active:not(.c-button--is-busy),.c-button--primary:active:not(.c-button--is-busy),.form-button:active:not(.c-button--is-busy){background-color:var(--global-color-accent--x-dark);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-light);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.button-wrapper button[type=submit]:focus:not(:active,.c-button--is-busy),.c-button--primary:focus:not(:active,.c-button--is-busy),.form-button:focus:not(:active,.c-button--is-busy){background-color:var(--global-color-accent--normal);border-color:var(--global-color-primary--xx-light);color:var(--global-color-primary--xx-light);outline:var(--global-border-width--normal) solid var(--global-color-accent--light)}.button-wrapper button[type=submit].c-button--is-busy,.button-wrapper button[type=submit]:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])),.c-button--primary.c-button--is-busy,.c-button--primary:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])),.form-button.c-button--is-busy,.form-button:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-accent--normal);border-color:var(--global-color-accent--normal);color:var(--global-color-primary--xx-light)}.c-button--secondary:hover{background-color:var(--global-color-accent--weak);border-color:var(--global-color-accent--normal);color:var(--global-color-primary--xx-dark)}.c-button--secondary:active:not(.c-button--is-busy){background-color:var(--global-color-accent--x-light);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.c-button--secondary:focus:not(:active,.c-button--is-busy){background-color:var(--global-color-accent--weak);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--thick) solid var(--global-color-accent--light)}.c-button--secondary.c-button--is-busy,.c-button--secondary:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-primary--x-light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark)}.c-button.c-button--secondary:disabled,.c-button.c-button--secondary:where(a[disabled]),/* for specificity to override */,/* for specificity to override */{background-color:var(--global-color-primary--x-light)}.c-button--tertiary:hover{background-color:var(--global-color-primary--light);border-color:var(--global-color-accent--dark);color:var(--global-color-primary--xx-dark)}.c-button--tertiary:active:not(.c-button--is-busy){background-color:var(--global-color-accent--x-light);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.c-button--tertiary:focus:not(:active,.c-button--is-busy){background-color:var(--global-color-primary--light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--thick) solid var(--global-color-accent--light)}.c-button--tertiary.c-button--is-busy,.c-button--tertiary:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-primary--xx-light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark)}.c-button--is-active:hover{background-color:var(--global-color-accent--alt);border-color:var(--global-color-accent--dark);color:var(--global-color-primary--xx-dark)}.c-button--is-active:active{background-color:var(--global-color-accent--x-light);border-color:var(--global-color-accent--dark);border-width:var(--global-border-width--normal);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--normal) solid var(--global-color-accent--dark)}.c-button--is-active:focus:not(:active){background-color:var(--global-color-accent--alt);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark);outline:var(--global-border-width--thick) solid var(--global-color-accent--light)}.c-button--is-active.c-button--is-busy,.c-button--is-active:not(.c-button:hover,.c-button:focus,.c-button:active,.c-button:disabled,.c-button:where(a[disabled])){background-color:var(--global-color-accent--x-light);border-color:var(--global-color-primary--xx-dark);color:var(--global-color-primary--xx-dark)}.c-button--as-link{background:unset;border:unset;font-family:inherit;font-size:inherit;padding-inline:unset}.c-button--is-busy{opacity:.5}.c-button--is-busy .c-button__text{opacity:.3}.button-wrapper button[type=submit]:not(.c-button--width-short,.c-button--width-medium,.c-button--width-long,.c-button--size-small,.c-button--as-link),.c-button:not(.c-button--width-short,.c-button--width-medium,.c-button--width-long,.c-button--size-small,.c-button--as-link),.form-button:not(.c-button--width-short,.c-button--width-medium,.c-button--width-long,.c-button--size-small,.c-button--as-link){--max-width:auto;width:auto}.c-button--width-short{width:var(--min-width)}.c-button--width-medium{width:var(--mid-width)}.c-button--width-long{width:var(--max-width)}.c-button--size-small{line-height:1;min-width:0;padding:4px 9px}.button-wrapper button[type=submit]>*,.c-button>*,.form-button>*{vertical-align:middle}.c-button__icon--before{margin-right:.5em}.c-button__icon--after{margin-left:.5em}.button-wrapper button[type=submit]:not(.c-button--as-link),.c-button:not(.c-button--as-link),.form-button:not(.c-button--as-link){font-size:var(--global-font-size--small)}.cms-ready{--cms-toolbar-height:46px}.cms-ready :target{scroll-margin-top:var(--cms-toolbar-height)}.cms-ready .position-sticky.fixed-top,.cms-ready .sticky-top{top:var(--cms-toolbar-height)}.field-wrapper.checkboxselectmultiple.required>label:after{border:var(--global-border--thick);display:block;font-size:var(--global-font-size--small);margin-top:.5em;padding:15px 20px}html[class*=cms-structure-mode-] .field-wrapper.checkboxselectmultiple.required>label:after{background-color:var(--global-color-danger--weak);border-color:var(--global-color-danger--normal);color:var(--global-color-danger--dark);content:"A multi checkbox field that is required is not well implemented. Do not require this field or replace it with multiple required Yes/No radio fields."}html:not([class*=cms-structure-mode-]) .field-wrapper.checkboxselectmultiple.required>label:after{background-color:var(--global-color-warning--weak);border-color:var(--global-color-warning--normal);color:var(--global-color-warning--dark);content:"This field is not well implemented. Select all boxes to bypass the error with this field."}.description{margin-block:25px}.help-text{font-size:var(--global-font-size--small);font-style:italic}:not(ul,label)+.help-text{margin-top:.3em}.help-text>:not(details,a,samp){font-style:normal}.field-wrapper{margin-bottom:2rem}.field-wrapper:not(.checkboxinput){display:flex;flex-direction:column}.field-wrapper:not(.checkboxinput)>.field-errors{order:1}.field-wrapper.checkboxinput{align-items:center;-moz-column-gap:.5em;column-gap:.5em;display:inline-grid;grid-template-areas:"error _____" "input label" "notes notes";grid-template-columns:min-content auto}.field-wrapper.checkboxinput .field-errors{grid-area:error}.field-wrapper.checkboxinput input{grid-area:input}.field-wrapper.checkboxinput label{grid-area:label}.field-wrapper.checkboxinput .help-text{grid-area:notes}.field-wrapper.checkboxinput label{margin-bottom:0}ul.checkboxselectmultiple label,ul.radioselect label{align-items:center;display:flex;gap:.5em}ul.checkboxselectmultiple li:last-child label,ul.radioselect li:last-child label{margin-bottom:0}.field-wrapper.required>label{font-weight:var(--bold)}.field-wrapper.required>label .asterisk{font-weight:var(--regular)}.field-wrapper.required:has(label .asterisk) label:has(sub,sup){align-items:center;display:flex}.field-wrapper .asterisk{margin-left:.5em}.field-wrapper.required .asterisk{color:var(--global-color-danger--dark)}.field-wrapper:not(.required) .asterisk{color:var(--global-color-warning--dark)}.field-wrapper .asterisk{display:inline-block;line-height:0;visibility:hidden;width:0}.field-wrapper .asterisk:after{line-height:normal;visibility:visible}.field-wrapper.required .asterisk:after{content:"(required)"}.field-wrapper:not(.required) .asterisk:after{content:"(important)"}.field-errors{font-size:var(--global-font-size--small)}.field-errors ul{margin-bottom:0;margin-top:1rem}ul.checkboxselectmultiple,ul.radioselect{list-style:none;padding-left:0}.button-wrapper{margin-top:35px}span.has-svg{display:inline-block}span.has-svg>svg{height:100%;width:100%}.align-left,.align-right{margin-bottom:var(--global-space--grid-gap)}.align-right{float:right;margin-left:var(--global-space--grid-gap)}.align-left{float:left;margin-right:var(--global-space--grid-gap)}.align-center{display:block;margin-inline:auto}.align-center:not(img):has(img){width:fit-content}.align-right+:not(img){clear:right}.align-left+:not(img){clear:left}nav.s-breadcrumbs{font-size:var(--global-font-size--x-small);padding-top:15px;text-transform:uppercase}nav.s-breadcrumbs ol{font-weight:var(--global-font-weight--medium);list-style:none;margin-bottom:unset;padding-left:unset}nav.s-breadcrumbs ol li,ol.s-breadcrumbs li{display:inline-block}nav.s-breadcrumbs ol li+li:before,ol.s-breadcrumbs li+li:before{content:" > "}nav.s-breadcrumbs ol li:last-child span{font-weight:var(--bold)}.s-footer>p:last-of-type{margin:0}.s-footer a{color:var(--global-color-primary--light)}.s-blockquote{margin-bottom:1.25em;margin-top:1.25em}.s-blockquote blockquote{font-size:1.125em;font-style:italic;margin-bottom:0}.s-blockquote blockquote p{margin:0;white-space:pre-wrap}.s-blockquote blockquote p:before{content:"“"}.s-blockquote blockquote p:after{content:"”"}.s-blockquote figcaption{font-size:1em;margin-top:.3em}.s-blockquote figcaption:before{content:"— "}.s-blockquote cite{font-style:normal}.u-mailto-text-replace[data-user][data-domain]{font-size:0;visibility:hidden}.u-mailto-text-replace[data-user][data-domain]:before{content:attr(data-user) "@" attr(data-domain);display:inline;font-size:medium;visibility:visible}.s-affixed-input-wrapper:not(.checkboxinput,.radio,.select,.checkboxselectmultiple,.textarea){align-items:start;display:grid;grid-template-areas:"label label" var(--input-row,"input input") "help help" "error error";grid-template-columns:auto 1fr}@supports selector(:has(*)){.s-affixed-input-wrapper:has(.s-affixed-input-wrapper__prefix){--input-row:"prefix input"}.s-affixed-input-wrapper:has(.s-affixed-input-wrapper__suffix){--input-row:"input suffix"}}@supports not selector(:has(*)){.s-affixed-input-wrapper--prefix{--input-row:"prefix input"}.s-affixed-input-wrapper--suffix{--input-row:"input suffix"}}.s-affixed-input-wrapper label{grid-area:label}.s-affixed-input-wrapper input{grid-area:input}.s-affixed-input-wrapper__prefix{grid-area:prefix}.s-affixed-input-wrapper__suffix{grid-area:suffix}.s-affixed-input-wrapper .help-text{grid-area:help}.s-affixed-input-wrapper .field-errors{grid-area:error}.s-affixed-input-wrapper{--width:1em;--padding-vert:5px;--padding-horz:10px}.s-affixed-input-wrapper__prefix,.s-affixed-input-wrapper__suffix{box-sizing:content-box;display:inline-block;font-family:var(--global-font-family--sans--portal);padding:var(--padding-vert) var(--padding-horz);pointer-events:none;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--width)}.s-affixed-input-wrapper__prefix{left:var(--global-border-width--normal);margin-right:calc(var(--width)*-1 - var(--padding-horz)*2);position:relative;top:var(--global-border-width--normal)}.s-affixed-input-wrapper__suffix{margin-left:calc(var(--width)*-1 - var(--padding-horz)*2);position:relative;right:var(--global-border-width--normal);top:var(--global-border-width--normal)}.s-affixed-input-wrapper__prefix+input{text-indent:calc(var(--width) + var(--padding-horz))} From 4e9b795ad7604ff6cef831d5a075669a19249948 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 24 Oct 2025 15:50:50 -0500 Subject: [PATCH 44/60] feat: serve page with no header nor footer (#1012) (#1013) --- taccsite_cms/settings_custom.example.py | 5 +++-- taccsite_cms/templates/base.html | 4 ++++ taccsite_cms/templates/content.html | 8 ++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100755 taccsite_cms/templates/content.html diff --git a/taccsite_cms/settings_custom.example.py b/taccsite_cms/settings_custom.example.py index edb635f26..e7b477b23 100644 --- a/taccsite_cms/settings_custom.example.py +++ b/taccsite_cms/settings_custom.example.py @@ -28,8 +28,9 @@ ('standard.html', 'Standard'), ('fullwidth.html', 'Full Width'), - # WARNING: Unintuitive, so only enable as needed e.g. TACC/Core-CMS#868 - # ('plain.html', 'Plain'), + # WARNING: Unintuitive, so only enable as needed + # ('plain.html', 'Plain'), # TACC/Core-CMS#868 + # ('content.html', 'Content Only'), # TACC/Core-CMS#___ ) ######################## diff --git a/taccsite_cms/templates/base.html b/taccsite_cms/templates/base.html index 357f57841..20da894c4 100755 --- a/taccsite_cms/templates/base.html +++ b/taccsite_cms/templates/base.html @@ -51,9 +51,11 @@ {% cms_toolbar %} + {% block header %}
{% include "header.html" %}
+ {% endblock header %}
{% block content %} @@ -79,7 +81,9 @@ {% endblock content %}
+ {% block footer %} {% include "footer.html" %} + {% endblock footer %} {% if settings.TACC_CORE_STYLES_VERSION == 0 %} diff --git a/taccsite_cms/templates/content.html b/taccsite_cms/templates/content.html new file mode 100755 index 000000000..046b4393b --- /dev/null +++ b/taccsite_cms/templates/content.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} +{% load cms_tags %} + +{% block header %}{% endblock %} + +{% include 'plain.html' %} + +{% block footer %}{% endblock %} From 594f31f25ec6989023b901ec9ed7c7b3d7dfb2e6 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 24 Oct 2025 16:24:11 -0500 Subject: [PATCH 45/60] fix: serve page with no header nor footer (#1014) (#1015) --- taccsite_cms/templates/content.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/taccsite_cms/templates/content.html b/taccsite_cms/templates/content.html index 046b4393b..5b5dd713e 100755 --- a/taccsite_cms/templates/content.html +++ b/taccsite_cms/templates/content.html @@ -3,6 +3,12 @@ {% block header %}{% endblock %} -{% include 'plain.html' %} +{# To remove container and breadcrumbs #} +{% block content %} + {% block cms_content %} + {% placeholder "content" %} + {% endblock cms_content %} + {% block app_content %}{% endblock app_content %} +{% endblock content %} {% block footer %}{% endblock %} From d620fee918f70e211a9f8249c18518227ccb831e Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Fri, 24 Oct 2025 17:33:14 -0500 Subject: [PATCH 46/60] feat: always allow CMS_TEMPLATE content.html (#1017) --- taccsite_cms/settings.py | 3 ++- taccsite_cms/settings_custom.example.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 0509b2107..3be443185 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -157,8 +157,9 @@ def gettext(s): return s CMS_TEMPLATES = ( ('standard.html', 'Standard'), ('fullwidth.html', 'Full Width'), + ('content.html', 'Content Only'), - ('guide.html', 'Guide'), + ('guide.html', 'Guide'), # backwards compatibility, users unknown ) CMS_PERMISSION = True diff --git a/taccsite_cms/settings_custom.example.py b/taccsite_cms/settings_custom.example.py index e7b477b23..d413f8860 100644 --- a/taccsite_cms/settings_custom.example.py +++ b/taccsite_cms/settings_custom.example.py @@ -27,10 +27,10 @@ CMS_TEMPLATES = ( ('standard.html', 'Standard'), ('fullwidth.html', 'Full Width'), + ('content.html', 'Content Only'), # WARNING: Unintuitive, so only enable as needed # ('plain.html', 'Plain'), # TACC/Core-CMS#868 - # ('content.html', 'Content Only'), # TACC/Core-CMS#___ ) ######################## From 445e4574bda78a894d68fd9ee2acd1dad70403d7 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:47:03 -0500 Subject: [PATCH 47/60] refactor: DJANGOCMS plugins settings (off main) (#1019) --- taccsite_cms/_settings/djangocms_plugins.py | 199 ++++++++++++++++++++ taccsite_cms/settings.py | 165 +--------------- 2 files changed, 202 insertions(+), 162 deletions(-) create mode 100644 taccsite_cms/_settings/djangocms_plugins.py diff --git a/taccsite_cms/_settings/djangocms_plugins.py b/taccsite_cms/_settings/djangocms_plugins.py new file mode 100644 index 000000000..d25ed7901 --- /dev/null +++ b/taccsite_cms/_settings/djangocms_plugins.py @@ -0,0 +1,199 @@ +"""Configure CMS plugins""" + +import os + +from django.utils.translation import gettext_lazy as _ + +######################## +# ../settings.py +######################## + +BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +######################## +# CKEDITOR +# https://github.com/django-cms/djangocms-text-ckeditor +######################## + +CKEDITOR_SETTINGS = { + 'autoParagraph': False, + 'stylesSet': 'default:/static/js/addons/ckeditor.wysiwyg.js', + 'contentsCss': ['/static/djangocms_text_ckeditor/ckeditor/contents.css'], +} + +######################## +# DJANGOCMS_PICTURE +# https://github.com/django-cms/djangocms-picture +######################## + +DJANGOCMS_PICTURE_NESTING = True +DJANGOCMS_PICTURE_RESPONSIVE_IMAGES = True +DJANGOCMS_PICTURE_RESPONSIVE_IMAGES_VIEWPORT_BREAKPOINTS = [ + 576, 768, 992, 1200, 1400, 1680, 1920 +] +DJANGOCMS_PICTURE_RATIO = 1.618 +DJANGOCMS_PICTURE_ALIGN = [ + ('left', _('Align left')), + ('right', _('Align right')), + ('center', _('Align center')), +] +DJANGOCMS_PICTURE_TEMPLATES = [ + ('no_link_to_ext_image', _('Do not link to "External image"')), + ('zoom_effect', _('Zoom image on hover')), + ('zoom_effect_no_link_to_ext_image', _('Zoom image on hover & Do not link to "External image"')), +] + +######################## +# DJANGOCMS_AUDIO +# https://github.com/django-cms/djangocms-audio +######################## + +DJANGOCMS_AUDIO_ALLOWED_EXTENSIONS = ['mp3', 'ogg', 'wav'] + +######################## +# DJANGOCMS_VIDEO +# https://github.com/django-cms/djangocms-video +######################## + +DJANGOCMS_VIDEO_TEMPLATES = [ + ('responsive-auto', _('Responsive - Automatic')), + ('responsive-16by9', _('Responsive - 16 by 9')), + ('responsive-4by3', _('Responsive - 4 by 3')), + ('responsive-1by1', _('Responsive - 1 by 1')), + ('responsive-21by9', _('Responsive - 21 by 9')), +] + +######################## +# DJANGOCMS_BOOTSTRAP +# https://github.com/django-cms/djangocms-bootstrap4 +######################## + +DJANGOCMS_BOOTSTRAP4_GRID_COLUMN_CHOICES = [ + ('col', _('Column')), + ('col col-dark', _('Dark column')), + ('col col-muted', _('Muted column')), + ('w-100', _('Break')), + ('', _('Empty')) +] + +DJANGOCMS_BOOTSTRAP4_GRID_CONTAINERS = [ + ('container', _('Container')), + ('container-fluid', _('Fluid container')), + ('o-section', _('Section')), + ('_', _('None')), + (_('Container'), ( + ( + 'container o-section', + _('Container + Section (transparent / margin)') + ), + ( + 'container o-section o-section--style-light', + _('Container + Light section') + ), + ( + 'container o-section o-section--style-muted', + _('Container + Muted section') + ), + ( + 'container o-section o-section--style-dark', + _('Container + Dark section') + ), + )), + (_('Fluid container'), ( + ( + 'container-fluid o-section', + _('Fluid container + Section (transparent / margin)') + ), + ( + 'container-fluid o-section o-section--style-light', + _('Fluid container + Light section') + ), + ( + 'container-fluid o-section o-section--style-muted', + _('Fluid container + Muted section') + ), + ( + 'container-fluid o-section o-section--style-dark', + _('Fluid container + Dark section') + ), + )), + (_('Section only'), ( + ( + 'o-section o-section--style-light', + _('Light section') + ), + ( + 'o-section o-section--style-muted', + _('Muted section') + ), + ( + 'o-section o-section--style-dark', + _('Dark section') + ), + )), +] + +######################## +# DJANGOCMS_STYLE +# https://github.com/django-cms/djangocms-style +######################## + +DJANGOCMS_STYLE_CHOICES = [ + 'card', + 'card--plain', + 'card--standard', + 'card--image-top', + 'card--image-bottom', + 'card--image-right', + 'card--image-left', + 'section', + 'section--light', + 'section--muted', + 'section--dark', + 'o-section', + 'o-section o-section--style-light', + 'o-section o-section--style-muted', + 'o-section o-section--style-dark', + 'c-callout', + 'c-recognition c-recognition--style-light', + 'c-recognition c-recognition--style-dark', + 'c-nav', # bare-bones instance + 'c-nav c-nav--boxed', +] + +DJANGOCMS_STYLE_TAGS = [ + # Even though
is often NOT the most semantic choice; + # CMS editor may neglect tag, any other tag could be inaccurate, + # and
is never inaccurate; so
is placed first 😞 + # RFE: Support automatically choosing tag based on class name + # SEE: https://github.com/TACC/Core-CMS/pull/432 + 'div', + # Ordered by expected usage + 'section', 'article', 'header', 'footer', 'aside', 'nav', + # Not expected but not unreasonable + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' +] + +######################## +# DJANGOCMS_ICON +# https://github.com/django-cms/djangocms-icon +######################## + +ICON_PATH = os.path.join('taccsite_cms', 'static', 'site_cms', 'img', 'icons') + +LOGO_ICONFILE = os.path.join(BASE_DIR, ICON_PATH, 'logos.json') +with open(LOGO_ICONFILE, 'r') as f: + LOGO_ICONS = f.read() + +CORTAL_ICONFILE = os.path.join(BASE_DIR, ICON_PATH, 'cortal.json') +with open(CORTAL_ICONFILE, 'r') as f: + CORTAL_ICONS = f.read() + +DJANGOCMS_ICON_SETS = [ + # IMPORTANT: Each set must have same props, even if value is empty + # WARNING: Values in icon sets are not cleared when user changes set + # IMPORTANT: Load 'icon' set last, or selected SVG may be unselected on edit + # https://github.com/django-cms/djangocms-icon/issues/9 + (LOGO_ICONS, '', _('Logo SVGs')), + (CORTAL_ICONS, 'icon', _('TACC "Cortal" Icons')), +] diff --git a/taccsite_cms/settings.py b/taccsite_cms/settings.py index 3be443185..461e63248 100644 --- a/taccsite_cms/settings.py +++ b/taccsite_cms/settings.py @@ -16,6 +16,7 @@ from taccsite_cms._settings.auth import * from taccsite_cms._settings.email import * +from taccsite_cms._settings.djangocms_plugins import * from taccsite_cms._settings.form_plugin import * from taccsite_cms._settings.form_plugin import ( _INSTALLED_APPS as form_plugin_INSTALLED_APPS @@ -580,23 +581,6 @@ def get_subdirs_as_module_names(path): 'easy_thumbnails.processors.filters' ) -DJANGOCMS_PICTURE_NESTING = True -DJANGOCMS_PICTURE_RESPONSIVE_IMAGES = True -DJANGOCMS_PICTURE_RESPONSIVE_IMAGES_VIEWPORT_BREAKPOINTS = [ - 576, 768, 992, 1200, 1400, 1680, 1920 -] -DJANGOCMS_PICTURE_RATIO = 1.618 -DJANGOCMS_PICTURE_ALIGN = [ - ('left', _('Align left')), - ('right', _('Align right')), - ('center', _('Align center')), -] -DJANGOCMS_PICTURE_TEMPLATES = [ - ('no_link_to_ext_image', _('Do not link to "External image"')), - ('zoom_effect', _('Zoom image on hover')), - ('zoom_effect_no_link_to_ext_image', _('Zoom image on hover & Do not link to "External image"')), -] - # FILE UPLOAD VALUES MUST BE SET! # Set in correlation with the `client_max_body_size 20m;` value in /etc/nginx/proxy.conf. # A problem comes from Django's usage of tempfile, which enforces new files to have permission @@ -605,160 +589,17 @@ def get_subdirs_as_module_names(path): FILE_UPLOAD_PERMISSIONS = 0o644 FILE_UPLOAD_MAX_MEMORY_SIZE = 20000000 # 20MB -DJANGOCMS_AUDIO_ALLOWED_EXTENSIONS = ['mp3', 'ogg', 'wav'] - ######################## -# PLUGIN SETTINGS +# META +# https://github.com/nephila/django-meta ######################## -# SEE: https://github.com/django-cms/djangocms-bootstrap4 -DJANGOCMS_BOOTSTRAP4_GRID_COLUMN_CHOICES = [ - ('col', _('Column')), - ('col col-dark', _('Dark column')), - ('col col-muted', _('Muted column')), - ('w-100', _('Break')), - ('', _('Empty')) -] - -# SEE: https://github.com/django-cms/djangocms-bootstrap4 -DJANGOCMS_BOOTSTRAP4_GRID_CONTAINERS = [ - ('container', _('Container')), - ('container-fluid', _('Fluid container')), - ('o-section', _('Section')), - ('_', _('None')), - (_('Container'), ( - ( - 'container o-section', - _('Container + Section (transparent / margin)') - ), - ( - 'container o-section o-section--style-light', - _('Container + Light section') - ), - ( - 'container o-section o-section--style-muted', - _('Container + Muted section') - ), - ( - 'container o-section o-section--style-dark', - _('Container + Dark section') - ), - )), - (_('Fluid container'), ( - ( - 'container-fluid o-section', - _('Fluid container + Section (transparent / margin)') - ), - ( - 'container-fluid o-section o-section--style-light', - _('Fluid container + Light section') - ), - ( - 'container-fluid o-section o-section--style-muted', - _('Fluid container + Muted section') - ), - ( - 'container-fluid o-section o-section--style-dark', - _('Fluid container + Dark section') - ), - )), - (_('Section only'), ( - ( - 'o-section o-section--style-light', - _('Light section') - ), - ( - 'o-section o-section--style-muted', - _('Muted section') - ), - ( - 'o-section o-section--style-dark', - _('Dark section') - ), - )), -] - -# https://github.com/django-cms/djangocms-style -DJANGOCMS_STYLE_CHOICES = [ - 'card', - 'card--plain', - 'card--standard', - 'card--image-top', - 'card--image-bottom', - 'card--image-right', - 'card--image-left', - 'section', - 'section--light', - 'section--muted', - 'section--dark', - 'o-section', - 'o-section o-section--style-light', - 'o-section o-section--style-muted', - 'o-section o-section--style-dark', - 'c-callout', - 'c-recognition c-recognition--style-light', - 'c-recognition c-recognition--style-dark', - 'c-nav', # bare-bones instance - 'c-nav c-nav--boxed', -] -DJANGOCMS_STYLE_TAGS = [ - # Even though
is often NOT the most semantic choice; - # CMS editor may neglect tag, any other tag could be inaccurate, - # and
is never inaccurate; so
is placed first 😞 - # RFE: Support automatically choosing tag based on class name - # SEE: https://github.com/TACC/Core-CMS/pull/432 - 'div', - # Ordered by expected usage - 'section', 'article', 'header', 'footer', 'aside', 'nav', - # Not expected but not unreasonable - 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' -] - -# https://github.com/nephila/django-meta META_SITE_PROTOCOL = 'http' META_USE_SITES = True META_USE_OG_PROPERTIES = True META_USE_TWITTER_PROPERTIES = True META_USE_SCHEMAORG_PROPERTIES = True -# https://github.com/django-cms/djangocms-text-ckeditor -CKEDITOR_SETTINGS = { - 'autoParagraph': False, - 'stylesSet': 'default:/static/js/addons/ckeditor.wysiwyg.js', - 'contentsCss': ['/static/djangocms_text_ckeditor/ckeditor/contents.css'], -} - -# https://github.com/django-cms/djangocms-video -DJANGOCMS_VIDEO_TEMPLATES = [ - ('responsive-auto', _('Responsive - Automatic')), - ('responsive-16by9', _('Responsive - 16 by 9')), - ('responsive-4by3', _('Responsive - 4 by 3')), - ('responsive-1by1', _('Responsive - 1 by 1')), - ('responsive-21by9', _('Responsive - 21 by 9')), -] - -# DJANGOCMS_ICON SETTINGS -# https://github.com/django-cms/djangocms-icon - -ICON_PATH = os.path.join('taccsite_cms', 'static', 'site_cms', 'img', 'icons') - -LOGO_ICONFILE = os.path.join(BASE_DIR, ICON_PATH, 'logos.json') -with open(LOGO_ICONFILE, 'r') as f: - LOGO_ICONS = f.read() - -CORTAL_ICONFILE = os.path.join(BASE_DIR, ICON_PATH, 'cortal.json') -with open(CORTAL_ICONFILE, 'r') as f: - CORTAL_ICONS = f.read() - -DJANGOCMS_ICON_SETS = [ - # IMPORTANT: Each set must have same props, even if value is empty - # WARNING: Values in icon sets are not cleared when user changes set - # IMPORTANT: Load 'icon' set last, or selected SVG may be unselected on edit - # https://github.com/django-cms/djangocms-icon/issues/9 - (LOGO_ICONS, '', _('Logo SVGs')), - (CORTAL_ICONS, 'icon', _('TACC "Cortal" Icons')), -] - ######################## # REDMINE TRACKER AUTH From 339a4403aa44cd02721de5153e30ea56c1ae0fda Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 30 Oct 2025 15:02:10 -0500 Subject: [PATCH 48/60] chore: v4.36.10 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9711919ff..af50175ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "v4.36.9" +version = "v4.36.10" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 3b522677acc2d171644a07af588635576d110751 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 11 Nov 2025 20:53:50 -0800 Subject: [PATCH 49/60] feat: support DjangoCMS Bootstrap4 Link/Button (#1020) * deps: core-styles v2.48 * deps: core-styles v2.50 for core-styles.bootstrap * fix: bootstrap4.css, not bootstrap.css * feat: do not deprecate Link / Button plugin * fix: .btn with .icon (FOR CORE-STYLES) * fix: .icon not working via djangocms-bootstrap4 https://github.com/django-cms/djangocms-bootstrap4/issues/124 * fix: load REAL Core-Styles v2.50 (TEMP FIX) * feat: NO preview for Bootstrap Link/Pluign render Because: 1. Using Core-Styles to skin it requires @layer's. - Cuz Core-Styles selectors are often less specific than Bootstrap. 2. Using @layer's requires the same for DJango CMS and Django. 3. Using @layer's for Django CMS nad Django is not worht the trouble. * deps: core-styles v2.50.1 * feat: remove link_outline and link_block options * feat: remove unsupported bootstrap "colors" might revisit this for alerta * feat: remove unsupported bootstrap button "size" * feat: rename Context to Type --- package-lock.json | 14 ++++---- package.json | 5 ++- taccsite_cms/_settings/djangocms_plugins.py | 13 ++++++++ taccsite_cms/apps.py | 2 ++ .../bootstrap4_djangocms_link/cms_plugins.py | 9 ----- .../contrib/bootstrap4_link/extend.py | 33 +++++++++++++++++++ .../_core-styles/core-styles.bootstrap.css | 2 ++ taccsite_cms/templates/assets_core.html | 3 +- .../djangocms_bootstrap4/admin/base.html | 20 +++++++++++ .../djangocms_icon/includes/icon.html | 3 ++ 10 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 taccsite_cms/djangocms_bootstrap4/contrib/bootstrap4_link/extend.py create mode 100644 taccsite_cms/static/site_cms/css/src/_core-styles/core-styles.bootstrap.css create mode 100644 taccsite_cms/templates/djangocms_bootstrap4/admin/base.html create mode 100644 taccsite_cms/templates/djangocms_icon/includes/icon.html diff --git a/package-lock.json b/package-lock.json index 113c7ff84..04cf8fb28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "minimist": "^1.2.6" }, "devDependencies": { - "@tacc/core-styles": "^2.47.3" + "@tacc/core-styles": "^2.50.1" }, "engines": { "node": ">=16", @@ -1132,9 +1132,9 @@ } }, "node_modules/@tacc/core-styles": { - "version": "2.47.3", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.47.3.tgz", - "integrity": "sha512-W+ol2BtrhEeWkimvMcjDg2sTsKW4Ri6ggYa4kPbJN9Okw/DyHmtCx+JTwUBAp+iDxUWCC+FaMOmi8ZqSnAeljA==", + "version": "2.50.1", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.50.1.tgz", + "integrity": "sha512-kAQF92Xc5PAsitV4RjA/PB/NNwIAnRzH42rjYgr2+0FAJDTWK5/F7S1pBA1RC5h0goDrSD6ZaDC4RuAKRohcgA==", "dev": true, "license": "MIT", "bin": { @@ -4733,9 +4733,9 @@ } }, "@tacc/core-styles": { - "version": "2.47.3", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.47.3.tgz", - "integrity": "sha512-W+ol2BtrhEeWkimvMcjDg2sTsKW4Ri6ggYa4kPbJN9Okw/DyHmtCx+JTwUBAp+iDxUWCC+FaMOmi8ZqSnAeljA==", + "version": "2.50.1", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.50.1.tgz", + "integrity": "sha512-kAQF92Xc5PAsitV4RjA/PB/NNwIAnRzH42rjYgr2+0FAJDTWK5/F7S1pBA1RC5h0goDrSD6ZaDC4RuAKRohcgA==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index 46479f38f..aa5a6d4ee 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,9 @@ }, "homepage": "https://github.com/TACC/Core-CMS", "devDependencies": { - "@tacc/core-styles": "^2.47.3" + "@tacc/core-styles": "^2.50.1" + }, + "// devDependencies": { + "@tacc/core-styles": "after v2.50.0, use NPM (because NPM and GitHub v2.50.0 differ)" } } diff --git a/taccsite_cms/_settings/djangocms_plugins.py b/taccsite_cms/_settings/djangocms_plugins.py index d25ed7901..5406aa1d9 100644 --- a/taccsite_cms/_settings/djangocms_plugins.py +++ b/taccsite_cms/_settings/djangocms_plugins.py @@ -133,6 +133,19 @@ )), ] +DJANGOCMS_BOOTSTRAP4_COLOR_STYLE_CHOICES = ( + ('primary', _('Primary')), + ('secondary', _('Secondary')), + # Disable for bootstrap4_link + # WARNING: Might still want for bootstrap4_alerts + # ('success', _('Success')), + # ('danger', _('Danger')), + # ('warning', _('Warning')), + # ('info', _('Info')), + ('light', _('Light')), + ('dark', _('Dark')), +) + ######################## # DJANGOCMS_STYLE # https://github.com/django-cms/djangocms-style diff --git a/taccsite_cms/apps.py b/taccsite_cms/apps.py index 64d8e4bde..478f0765d 100644 --- a/taccsite_cms/apps.py +++ b/taccsite_cms/apps.py @@ -4,6 +4,7 @@ from django.db.models.signals import post_migrate from .djangocms_picture.extend import extendPicturePlugin +from .djangocms_bootstrap4.contrib.bootstrap4_link.extend import extendBootstrap4LinkPlugin logger = logging.getLogger(f"portal.{__name__}") @@ -14,6 +15,7 @@ class TaccsiteCmsConfig(AppConfig): def ready(self): post_migrate.connect(self.create_groups, sender=self) extendPicturePlugin() + extendBootstrap4LinkPlugin() def create_groups(self, sender, **kwargs): from django.contrib.auth.models import Group diff --git a/taccsite_cms/contrib/bootstrap4_djangocms_link/cms_plugins.py b/taccsite_cms/contrib/bootstrap4_djangocms_link/cms_plugins.py index 6b287e6a8..6c408d2a2 100644 --- a/taccsite_cms/contrib/bootstrap4_djangocms_link/cms_plugins.py +++ b/taccsite_cms/contrib/bootstrap4_djangocms_link/cms_plugins.py @@ -29,15 +29,6 @@ } ) - # To signal to users that plugin is not desirable - Bootstrap4LinkPlugin.name = _('⚠️ Link / Button') - Bootstrap4LinkPlugin.fieldsets.insert(0, ( - None, { - 'description': _('⚠️ This plugin is deprecated. Please use "Generic" > "Link" plugin instead.
If the "Generic" > "Link" plugin is inadequate, please inform the CMS development team.'), - 'fields': () - } - )) - # To re-register generic Link plugin # SEE: https://github.com/django-cms/djangocms-bootstrap4/blob/master/djangocms_bootstrap4/contrib/bootstrap4_link/cms_plugins.py#L81 plugin_pool.register_plugin(LinkPlugin) diff --git a/taccsite_cms/djangocms_bootstrap4/contrib/bootstrap4_link/extend.py b/taccsite_cms/djangocms_bootstrap4/contrib/bootstrap4_link/extend.py new file mode 100644 index 000000000..868c4d51b --- /dev/null +++ b/taccsite_cms/djangocms_bootstrap4/contrib/bootstrap4_link/extend.py @@ -0,0 +1,33 @@ +def extendBootstrap4LinkPlugin(): + import copy + + from django.utils.translation import gettext_lazy as _ + + from cms.plugin_pool import plugin_pool + + from djangocms_bootstrap4.contrib.bootstrap4_link.cms_plugins import Bootstrap4LinkPlugin as OriginalBootstrap4LinkPlugin + from djangocms_bootstrap4.contrib.bootstrap4_link.models import Bootstrap4Link as OriginalBootstrap4Link + + class Bootstrap4LinkModel(OriginalBootstrap4Link): + class Meta: + proxy = True + + LINK_SIZE_CHOICES = ( + ('btn-sm', _('Small')), + ('', _('Regular')), + ) + + OriginalBootstrap4Link._meta.get_field('link_size').choices = LINK_SIZE_CHOICES + OriginalBootstrap4Link._meta.get_field('link_context').verbose_name = _('Type') + + class Bootstrap4LinkPlugin(OriginalBootstrap4LinkPlugin): + model = Bootstrap4LinkModel + + original_fields = OriginalBootstrap4LinkPlugin.fieldsets[0][1]['fields'] + filtered_fields = tuple(f for f in original_fields if f != ('link_outline', 'link_block')) + + fieldsets = list(copy.deepcopy(OriginalBootstrap4LinkPlugin.fieldsets)) + fieldsets[0] = (None, {'fields': filtered_fields}) + + plugin_pool.unregister_plugin(OriginalBootstrap4LinkPlugin) + plugin_pool.register_plugin(Bootstrap4LinkPlugin) diff --git a/taccsite_cms/static/site_cms/css/src/_core-styles/core-styles.bootstrap.css b/taccsite_cms/static/site_cms/css/src/_core-styles/core-styles.bootstrap.css new file mode 100644 index 000000000..02128d4a5 --- /dev/null +++ b/taccsite_cms/static/site_cms/css/src/_core-styles/core-styles.bootstrap.css @@ -0,0 +1,2 @@ +/* TODO: Host Core-Styles static files on a CDN */ +@import url("@tacc/core-styles/dist/core-styles.bootstrap4.css"); diff --git a/taccsite_cms/templates/assets_core.html b/taccsite_cms/templates/assets_core.html index 4597aa37f..1cb8e313f 100644 --- a/taccsite_cms/templates/assets_core.html +++ b/taccsite_cms/templates/assets_core.html @@ -6,6 +6,7 @@ @layer foundation, base, project; /* TODO: Use same version of Bootstrap as TACC/Core-Portal (v5) */ - @import url("https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css") layer(foundation); + @import url("https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css") layer(foundation); + @import url("{% static 'site_cms/css/build/core-styles.bootstrap.css' %}") layer(foundation); @import url("{% static 'site_cms/css/build/core-styles.base.css' %}") layer(base); diff --git a/taccsite_cms/templates/djangocms_bootstrap4/admin/base.html b/taccsite_cms/templates/djangocms_bootstrap4/admin/base.html new file mode 100644 index 000000000..3885d0cb8 --- /dev/null +++ b/taccsite_cms/templates/djangocms_bootstrap4/admin/base.html @@ -0,0 +1,20 @@ +{# https://github.com/django-cms/djangocms-bootstrap4/blob/3.0.2/djangocms_bootstrap4/templates/djangocms_bootstrap4/admin/base.html #}{% extends "admin/cms/page/plugin/change_form.html" %} +{% load static %} + +{% block extrahead %} + {{ block.super }} + {# TACC: Do not load Bootstrap (to skin preview is too cumbersome) #} + {% comment %} + + + {% endcomment %} + {# /TACC #} +{% endblock %} + +{% block field_sets %} +
+ {% block custom_message %}{% endblock %} + {{ block.super }} +
+{% endblock %} diff --git a/taccsite_cms/templates/djangocms_icon/includes/icon.html b/taccsite_cms/templates/djangocms_icon/includes/icon.html new file mode 100644 index 000000000..6512c2a97 --- /dev/null +++ b/taccsite_cms/templates/djangocms_icon/includes/icon.html @@ -0,0 +1,3 @@ +{# https://github.com/django-cms/djangocms-icon/blob/2.1.0/djangocms_icon/templates/djangocms_icon/includes/icon.html #} + +{% load cms_tags %} From 9e7b30569976dd869a7356045f094723eea8a890 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 11 Nov 2025 20:56:37 -0800 Subject: [PATCH 50/60] fix: core-styles v2.50.2 (#1021) --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 04cf8fb28..00b7e61e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "minimist": "^1.2.6" }, "devDependencies": { - "@tacc/core-styles": "^2.50.1" + "@tacc/core-styles": "^2.50.2" }, "engines": { "node": ">=16", @@ -1132,9 +1132,9 @@ } }, "node_modules/@tacc/core-styles": { - "version": "2.50.1", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.50.1.tgz", - "integrity": "sha512-kAQF92Xc5PAsitV4RjA/PB/NNwIAnRzH42rjYgr2+0FAJDTWK5/F7S1pBA1RC5h0goDrSD6ZaDC4RuAKRohcgA==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.50.2.tgz", + "integrity": "sha512-H0UylyJ5BsEa3dyvrV+rGH1ZQJoHJq3W5M904d/d+rWbc7kXiOtsCZsp535o8etRiTC4JmyS2k40MVVv9OKpKw==", "dev": true, "license": "MIT", "bin": { @@ -4733,9 +4733,9 @@ } }, "@tacc/core-styles": { - "version": "2.50.1", - "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.50.1.tgz", - "integrity": "sha512-kAQF92Xc5PAsitV4RjA/PB/NNwIAnRzH42rjYgr2+0FAJDTWK5/F7S1pBA1RC5h0goDrSD6ZaDC4RuAKRohcgA==", + "version": "2.50.2", + "resolved": "https://registry.npmjs.org/@tacc/core-styles/-/core-styles-2.50.2.tgz", + "integrity": "sha512-H0UylyJ5BsEa3dyvrV+rGH1ZQJoHJq3W5M904d/d+rWbc7kXiOtsCZsp535o8etRiTC4JmyS2k40MVVv9OKpKw==", "dev": true, "requires": {} }, diff --git a/package.json b/package.json index aa5a6d4ee..13f1f5149 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "homepage": "https://github.com/TACC/Core-CMS", "devDependencies": { - "@tacc/core-styles": "^2.50.1" + "@tacc/core-styles": "^2.50.2" }, "// devDependencies": { "@tacc/core-styles": "after v2.50.0, use NPM (because NPM and GitHub v2.50.0 differ)" From 7eace569e4482f1c8104d41beeabde4f57b29066 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Tue, 11 Nov 2025 23:07:25 -0600 Subject: [PATCH 51/60] chore: v4.36.11 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index af50175ef..2c2ce23dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "v4.36.10" +version = "v4.36.11" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 70141acc2b0a1fb609b6483a0ca8c1d046e7c7f5 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 13:00:32 -0800 Subject: [PATCH 52/60] fix: link-wrapped img ignores box-model (#1023) So add new class on wrap, and use it to support box model. --- .../_imports/components/django.cms.picture.css | 18 ++++++++---------- .../djangocms_picture/default/picture.html | 9 ++++++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.picture.css b/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.picture.css index ee1caa672..623683b3e 100644 --- a/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.picture.css +++ b/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.picture.css @@ -2,10 +2,9 @@ /* SEE: https://github.com/django-cms/djangocms-picture/blob/2.3.0/djangocms_picture/models.py#L24-L34 */ @import url("@tacc/core-styles/src/lib/_imports/components/align.css"); -/* Allow anchor tag to wrap like a block but still behave inline */ -/* FAQ: TACC/Core-CMS causes this tag-class combination, so it must manage it */ -/* FAQ: TACC/Core-CMS moves (side effect) Picture classes to
or */ -a.img-fluid { +/* Give linked image same box-model behavior as image */ +/* FAQ: Not doing this for `figure` cuz it is already a block */ +a.editor-img-wrap { display: inline-block; } @@ -26,11 +25,11 @@ img.align-center { /* To apply djangocms-bootstrap4/…_picture class styles from parent to image */ /* FAQ: TACC/Core-CMS moves (side effect) Picture classes to
or */ /* SEE: taccsite_cms/templates/djangocms_picture/default/picture.html */ -:is(figure, a).img-fluid img { +.editor-img-wrap:is(figure, a).img-fluid img { max-width: 100%; height: auto; } -:is(figure, a).img-thumbnail img { +.editor-img-wrap:is(figure, a).img-thumbnail img { padding: 0.25rem; background-color: #fff; border: 1px solid #dee2e6; @@ -38,19 +37,18 @@ img.align-center { max-width: 100%; height: auto; } -:is(figure, a).rounded img { +.editor-img-wrap:is(figure, a).rounded img { /* NOTE: Bootstrap used 0.25rem */ border-radius: 1rem !important; /* overwrite Bootstrap (uses !important) */ } /* To undo some djangocms-bootstrap4/…_picture class styles on parent */ /* FAQ: The duplicate styles on parent tags look odd or are unnecessary */ -:is(figure, a).img-thumbnail { +.editor-img-wrap:is(figure, a).img-thumbnail { padding: unset; background-color: unset; border: unset; border-radius: unset; } -:is(figure, a).rounded { +.editor-img-wrap:is(figure, a).rounded { border-radius: unset !important; /* overwrite Bootstrap (uses !important) */ } - diff --git a/taccsite_cms/templates/djangocms_picture/default/picture.html b/taccsite_cms/templates/djangocms_picture/default/picture.html index 463006bb3..92ea2666f 100644 --- a/taccsite_cms/templates/djangocms_picture/default/picture.html +++ b/taccsite_cms/templates/djangocms_picture/default/picture.html @@ -15,6 +15,7 @@ {% if instance.link_target %} target="{{ instance.link_target }}"{% endif %} {# TACC (support image zoom): #} class=" + editor-img-wrap {{ instance.attributes.class|default:'' }} {{ instance.link_attributes.class|default:'' }} {{ className }} @@ -33,7 +34,13 @@ {% if has_figure_content %} {# /TACC #} {# TACC (assign attributes to parent): #} -
+
{# /TACC #} {% endif %} From 4ef206bdf52f9bf295602ca607a18236d43562f4 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 14:05:43 -0800 Subject: [PATCH 53/60] feat/new-email-svg (#1024) --- taccsite_cms/static/site_cms/img/org_logos/email.svg | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/taccsite_cms/static/site_cms/img/org_logos/email.svg b/taccsite_cms/static/site_cms/img/org_logos/email.svg index f8758cbc4..c3292d87e 100644 --- a/taccsite_cms/static/site_cms/img/org_logos/email.svg +++ b/taccsite_cms/static/site_cms/img/org_logos/email.svg @@ -1,12 +1,4 @@ - - - + Email - - - - - - - + From 82cbb84415d1d49db8a6ac06a9ac24c7b0482c60 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 14:35:26 -0800 Subject: [PATCH 54/60] fix: social media icons were giant by default (#1026) * fix: social media icons need not default giant * fix: prevent underline of extra space on hover by removing extra space --- .../static/site_cms/css/src/_imports/components/logos.css | 3 +++ taccsite_cms/static/site_cms/css/src/core-cms.css | 1 + taccsite_cms/templates/share_on_social.html | 8 ++++---- 3 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 taccsite_cms/static/site_cms/css/src/_imports/components/logos.css diff --git a/taccsite_cms/static/site_cms/css/src/_imports/components/logos.css b/taccsite_cms/static/site_cms/css/src/_imports/components/logos.css new file mode 100644 index 000000000..b06c6bb42 --- /dev/null +++ b/taccsite_cms/static/site_cms/css/src/_imports/components/logos.css @@ -0,0 +1,3 @@ +.logos--social a { + display: inline-block; +} diff --git a/taccsite_cms/static/site_cms/css/src/core-cms.css b/taccsite_cms/static/site_cms/css/src/core-cms.css index 5ad491508..9817394ec 100644 --- a/taccsite_cms/static/site_cms/css/src/core-cms.css +++ b/taccsite_cms/static/site_cms/css/src/core-cms.css @@ -15,3 +15,4 @@ @import url("./_imports/components/django.cms.picture.css"); @import url("./_imports/components/django-cms-video.css"); @import url("./_imports/components/lightgallery.css"); +@import url("./_imports/components/logos.css"); diff --git a/taccsite_cms/templates/share_on_social.html b/taccsite_cms/templates/share_on_social.html index 846ea83ff..75a5283d7 100644 --- a/taccsite_cms/templates/share_on_social.html +++ b/taccsite_cms/templates/share_on_social.html @@ -12,28 +12,28 @@ {% for platform in platforms %} {% if platform == 'facebook' %} {% endif %} {% if platform == 'linkedin' %} - + {% endif %} {% if platform == 'bluesky' %} - + {% endif %} {% if platform == 'email' %} From 97ccb584f1408c2f3fc6eeadd6e552c1e9de4d19 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 18:35:56 -0600 Subject: [PATCH 55/60] refactor: simpler svg data for core logo --- taccsite_cms/static/site_cms/img/logo.svg | 31 +++++++++-------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/taccsite_cms/static/site_cms/img/logo.svg b/taccsite_cms/static/site_cms/img/logo.svg index 0ed876ae8..4b23fe8b5 100644 --- a/taccsite_cms/static/site_cms/img/logo.svg +++ b/taccsite_cms/static/site_cms/img/logo.svg @@ -1,20 +1,13 @@ - - - - - - - - - - - - - - - \ No newline at end of file + From e6685c0bdab7a4b4fb27968dc944c42698242b80 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 16:52:09 -0800 Subject: [PATCH 56/60] feat: logo icons inherit color & size (#1027) * feat: logo icons inherit color * feat: organization logos inherit color * feat: core logo inherit color * feat: logos inherit size * fix: ending `

` tag * feat: Icon svg inherit size * fix: no empty underlined space on hover * fix: tacc formal logo fill wrong * fix: bluesky logo duplicate code * feat: color icons * fix: bust cache --- .../css/src/_imports/components/logos.css | 40 ++++++++++++++++++- .../static/site_cms/img/icons/logos.svg | 8 ++-- .../static/site_cms/img/org_logos/bluesky.svg | 2 +- .../static/site_cms/img/org_logos/email.svg | 2 +- .../site_cms/img/org_logos/facebook.svg | 2 +- .../site_cms/img/org_logos/instagram.svg | 2 +- .../site_cms/img/org_logos/linkedin.svg | 2 +- .../site_cms/img/org_logos/nsf-logo.svg | 2 +- .../site_cms/img/org_logos/tacc-formal.svg | 2 +- .../static/site_cms/img/org_logos/threads.svg | 3 +- .../static/site_cms/img/org_logos/twitter.svg | 2 +- .../site_cms/img/org_logos/ut-informal.svg | 2 +- .../site_cms/img/org_logos/ut-primary.svg | 2 +- .../static/site_cms/img/org_logos/youtube.svg | 2 +- .../djangocms_icon/includes/svg.html | 2 +- taccsite_cms/templates/share_on_social.html | 8 ++-- .../templates/snippets/logos-branding.html | 12 +++--- .../snippets/logos-social-media.html | 31 +++++++------- 18 files changed, 81 insertions(+), 45 deletions(-) diff --git a/taccsite_cms/static/site_cms/css/src/_imports/components/logos.css b/taccsite_cms/static/site_cms/css/src/_imports/components/logos.css index b06c6bb42..17d874fa5 100644 --- a/taccsite_cms/static/site_cms/css/src/_imports/components/logos.css +++ b/taccsite_cms/static/site_cms/css/src/_imports/components/logos.css @@ -1,3 +1,41 @@ -.logos--social a { +/* Structure */ + +[class*="logos--"] a { display: inline-block; } +[class*="logos--"] a svg { + display: block; +} + + +/* Skin */ + +[class*="logos--"] a { + color: var(--global-color-primary--x-dark); +} +[class*="logos--"] a:hover { + color: var(--global-color-accent--normal); +} +a.logos__facebook:hover svg { color: #0866ff; } +a.logos__linkedin:hover svg { color: #0a66c2; } +a.logos__bluesky:hover svg { color: #0085ff; } +a.logos__youtube:hover svg { color: #FF0033; } + +a.logos__instagram:hover { + background: + radial-gradient(circle at 30% 107%, + rgba(140, 58, 170, 0) 0%, + rgba(140, 58, 170, 0) 64%, + rgba(140, 58, 170, 1) 100% + ), + radial-gradient(circle at 10% 105%, + #fa8f21 0%, + #fa8f21 9%, + #d82d7e 78% + ); + mask: url('../../img/org_logos/instagram.svg') no-repeat center / contain; + color: #bc1888; /* fallback */ +} +a.logos__instagram:hover svg { + visibility: hidden; +} diff --git a/taccsite_cms/static/site_cms/img/icons/logos.svg b/taccsite_cms/static/site_cms/img/icons/logos.svg index 625359fe0..c7bc67d64 100644 --- a/taccsite_cms/static/site_cms/img/icons/logos.svg +++ b/taccsite_cms/static/site_cms/img/icons/logos.svg @@ -2,19 +2,19 @@ -

- + Texas Advanced Computing Center - + - + Bluesky - + - + University of Texas at Austin - +

diff --git a/taccsite_cms/templates/snippets/logos-social-media.html b/taccsite_cms/templates/snippets/logos-social-media.html index ccdfd6083..23e887a25 100644 --- a/taccsite_cms/templates/snippets/logos-social-media.html +++ b/taccsite_cms/templates/snippets/logos-social-media.html @@ -1,46 +1,45 @@

+

From f0dae3444f230cf3aa2b4776ffad6dc2befc2d00 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 18:57:13 -0600 Subject: [PATCH 57/60] chore v4.36.12 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2c2ce23dc..569aa7296 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "v4.36.11" +version = "v4.36.12" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From 273bb043a82e8da8ac69038b28c0e4d66d10524d Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 17:28:20 -0800 Subject: [PATCH 58/60] feat: remove redundant social media icons - off main (#1031) feat: support DjangoCMS Bootstrap4 Link/Button (#1020) (#1022) (#1030) fix: remove redundtant social media icon css --- .../_imports/components/django.cms.blog.app.css | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.css b/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.css index 9e4035428..322a0403b 100644 --- a/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.css +++ b/taccsite_cms/static/site_cms/css/src/_imports/components/django.cms.blog.app.css @@ -144,27 +144,20 @@ Styleguide Components.DjangoCMS.Blog.App display: flex; flex-wrap: wrap; justify-self: end; -} - -.app-blog .logos--social > a { - display: flex; /* to vertically center the svg (as needed) */ @media (pointer: coarse) { - padding-inline: 0.5em; + gap: 1.0em; } @media not (pointer: coarse) { - padding-inline: 0.25em; + gap: 0.5em; } } .app-blog .logos__text-before { white-space: nowrap; - margin-right: 0.25em; } .app-blog .logos--social svg { - fill: var(--global-color-primary--x-dark); - @media (pointer: coarse) { height: var(--global-font-size--xx-large); width: var(--global-font-size--xx-large); @@ -174,11 +167,6 @@ Styleguide Components.DjangoCMS.Blog.App width: var(--global-font-size--large); } } -.app-blog a.logos__facebook:hover svg { fill: #0866ff; } -.app-blog a.logos__linkedin:hover svg { fill: #0a66c2; } -.app-blog a.logos__email:hover svg { fill: #0000ff; } -.app-blog a.logos__bluesky:hover svg { fill: #0085ff; } -.app-blog a.logos__instagram:hover svg { fill: #bc1888; } From dd9859788bb52a44fa898a5068d32050ed89aa62 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Thu, 13 Nov 2025 19:29:32 -0600 Subject: [PATCH 59/60] chore v4.36.13 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 569aa7296..c7f348ae7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "v4.36.12" +version = "v4.36.13" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "] From a8493923c7587a68bc0291e375afd7eb727341f2 Mon Sep 17 00:00:00 2001 From: Wesley B <62723358+wesleyboar@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:01:57 -0600 Subject: [PATCH 60/60] chore: v4.36.14 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c7f348ae7..e58c7c762 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tacc-core-cms-backend" -version = "v4.36.13" +version = "v4.36.14" description = "DjangoCMS backend for the TACC ACI-WMA Core-CMS Codebase." authors = ["TACC-WMA "]