diff --git a/djangoproject/scss/_style.scss b/djangoproject/scss/_style.scss index 3a6eb69d02..e958292c2c 100644 --- a/djangoproject/scss/_style.scss +++ b/djangoproject/scss/_style.scss @@ -3318,6 +3318,20 @@ hr { } } +/* Improve accessibility for footnote links in tables */ +table sup a, +.django-supported-versions sup a, +.django-unsupported-versions sup a { + color: var(--link-color); + text-decoration: underline; + + &:hover, + &:focus { + color: var(--primary-accent); + text-decoration: underline; + } +} + form .footnote { margin-top: 10px; text-align: left; diff --git a/djangoproject/settings/common.py b/djangoproject/settings/common.py index fff6e1dfee..d9bd12c31d 100644 --- a/djangoproject/settings/common.py +++ b/djangoproject/settings/common.py @@ -57,6 +57,7 @@ FIXTURE_DIRS = [str(PROJECT_PACKAGE.joinpath("fixtures"))] INSTALLED_APPS = [ + "djangoproject", # Add main project app for template tags "accounts", "aggregator", "blog", diff --git a/djangoproject/templates/base_lite.html b/djangoproject/templates/base_lite.html new file mode 100644 index 0000000000..e902a0d8ee --- /dev/null +++ b/djangoproject/templates/base_lite.html @@ -0,0 +1,97 @@ +{% load static %} + + + + + + + + + + + + {% block link_rel_tags %}{% endblock link_rel_tags %} + + + + + + + + + + {% block og_tags %} + + + + + + + + + + + + + + {% endblock og_tags %} + + {% block title %}Django{% endblock %} + + {% comment %} + Custom stylesheets block - allows for completely different styling + By default, no stylesheets are included to allow for custom styling + {% endcomment %} + {% block stylesheets %} + {% comment %} + Example usage: + {% block stylesheets %} + + + {% endblock %} + {% endcomment %} + {% endblock stylesheets %} + + {% block head_extra %}{% endblock head_extra %} + + + + {% comment %} + Skip link for accessibility - can be overridden if needed + {% endcomment %} + {% block skip_link %} + + {% endblock skip_link %} + + {% comment %} + Optional minimal header - can be completely overridden or omitted + {% endcomment %} + {% block header %}{% endblock header %} + + {% comment %} + Main content area - completely flexible + {% endcomment %} +
+ {% block content %}{% endblock content %} +
+ + {% comment %} + Optional footer - can be completely overridden or omitted + {% endcomment %} + {% block footer %}{% endblock footer %} + + {% comment %} + Minimal JavaScript block - only includes essentials + Can be overridden for custom JS needs + {% endcomment %} + {% block javascript %} + {% comment %} + Add any essential JavaScript here or override completely + {% endcomment %} + {% endblock javascript %} + + {% block body_extra %}{% endblock body_extra %} + + diff --git a/djangoproject/templates/flatpages/lite.html b/djangoproject/templates/flatpages/lite.html new file mode 100644 index 0000000000..a434b91d05 --- /dev/null +++ b/djangoproject/templates/flatpages/lite.html @@ -0,0 +1,71 @@ +{% extends "base_lite.html" %} +{% load static lite_filters %} + +{% comment %} +Lite flatpage template for documents with custom styling + +This template is designed for one-off documents like annual reports, +special publications, or any content that needs completely different +styling from the main Django website. + +Usage: +1. Create your flatpage in Django admin +2. Set the template name to "flatpages/lite.html" +3. Add custom CSS by creating blocks in your content or + by extending this template further + +Example custom styling approaches: + +Approach 1: Inline styles in flatpage content + + +Approach 2: External stylesheet in flatpage content + + +Approach 3: Create a custom template that extends this one +{% extends "flatpages/lite.html" %} +{% block stylesheets %} + +{% endblock %} +{% endcomment %} + +{% block title %}{{ flatpage.title }}{% endblock %} +{% block og_title %}{{ flatpage.title }}{% endblock %} + +{% comment %} +Extract CSS and JS from flatpage content if present +This allows content editors to include custom styles directly in the content +{% endcomment %} +{% block stylesheets %} + {% comment %} + Extract any or " + + # Find all matches + links = re.findall(link_pattern, value, re.IGNORECASE | re.DOTALL) + styles = re.findall(style_pattern, value, re.IGNORECASE | re.DOTALL) + + # Combine and return + head_content = "\n".join(links + styles) + return mark_safe(head_content) + + +@register.filter +def remove_head_tags(value): + """ + Remove and ", "", value, flags=re.IGNORECASE | re.DOTALL + ) + + return mark_safe(value) + + +@register.filter +def extract_script_tags(value): + """ + Extract " + + # Find all matches + scripts = re.findall(script_pattern, value, re.IGNORECASE | re.DOTALL) + + return mark_safe("\n".join(scripts)) + + +@register.filter +def remove_script_tags(value): + """ + Remove ", "", value, flags=re.IGNORECASE | re.DOTALL + ) + + return mark_safe(value) + + +@register.filter +def clean_content_for_lite(value): + """ + Combined filter to clean flatpage content for lite templates + Removes both head tags and script tags + + Usage: {{ flatpage.content|clean_content_for_lite }} + """ + if not value: + return "" + + # Remove head tags first, then script tags + value = remove_head_tags(value) + value = remove_script_tags(value) + + return value