fix: исправление мета-тегов, картинок, альтов под картинками и т.п.

This commit is contained in:
2026-01-31 01:48:09 +03:00
parent 884e00f730
commit 4791b9ed16
3 changed files with 74 additions and 60 deletions

View File

@@ -1,14 +1,18 @@
{% extends 'typograph/base.html' %} {% extends 'typograph/base.html' %}
{% load static %} {% load static %}
{% load typograph_extras %}
{% block title %}{{ page.seo_title|default:page.title }} — ETPGRF{% endblock %}
{% block description %}{{ page.seo_description|default:page.content|striptags|truncatechars:160 }}{% endblock %}
{% block keywords %}{{ page.seo_keywords|default:'типограф, типографика, онлайн типограф, подготовка текста для веба, html типограф, неразрывные пробелы, кавычки елочки, длинное тире, очистка текста от мусора, интернет верстка, муравьев' }} seo_keywords {% endblock %} {% block title %}{% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title|striptags|unescape|safe }}{% endif %} — ETPGRF{% endblock %}
{% block og_title %}{{ page.seo_title|default:page.title }}{% endblock %} {% block description %}{% if page.seo_description %}{{ page.seo_description }}{% else %}{{ page.excerpt|striptags|unescape|safe|truncatechars:160 }}{% endif %}{% endblock %}
{% block og_description %}{{ page.seo_description|default:page.content|striptags|truncatechars:160 }}{% endblock %} {% block keywords %}{% if page.seo_keywords %}{{ post.seo_keywords }}{% else %}типограф, типографика, блог типограф, онлайн типограф, подготовка текста для веба, html типограф, неразрывные пробелы, кавычки елочки, длинное тире, очистка текста от мусора, интернет верстка, муравьев, лебедев{% endif %}{% endblock %}
{% block og_title %}{% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title|striptags|unescape|safe }}{% endif %}{% endblock %}
{% block og_description %}{% if page.seo_description %}{{ page.seo_description }}{% else %}{{ page.excerpt|safe|striptags|unescape|truncatechars:160 }}{% endif %}{% endblock %}
{% block og_image %}{% if page.image %}{{ request.scheme }}://{{ request.get_host }}{{ page.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %} {% block og_image %}{% if page.image %}{{ request.scheme }}://{{ request.get_host }}{{ page.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %}
{% block twitter_title %}{{ page.seo_title|default:page.title }}{% endblock %} {% block twitter_title %}{% if page.seo_title %}{{ page.seo_title }}{% else %}{{ page.title|striptags|unescape|safe }}{% endif %}{% endblock %}
{% block twitter_description %}{{ page.seo_description|default:page.content|striptags|truncatechars:160 }}{% endblock %} {% block twitter_description %}{% if page.seo_description %}{{ page.seo_description }}{% else %}{{ page.excerpt|striptags|unescape|safe|truncatechars:160 }}{% endif %}{% endblock %}
{% block twitter_image %}{% if page.image %}{{ request.scheme }}://{{ request.get_host }}{{ page.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %} {% block twitter_image %}{% if page.image %}{{ request.scheme }}://{{ request.get_host }}{{ page.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %}
{% block content %} {% block content %}
@@ -17,33 +21,28 @@
{# Левая колонка: Дата и Картинка #} {# Левая колонка: Дата и Картинка #}
<div class="col-lg-2 align-self-start text-end mb-4"> <div class="col-lg-2 align-self-start text-end mb-4">
<p class="small align-self-end"> <p class="small align-self-end">
<small class="bg-secondary bg-opacity-10 p-2 text-nowrap"> <small class="bg-secondary bg-opacity-10 p-2 text-nowrap">{{ page.published_at|date:"d.M.Y"|lower }}</small>
{{ page.published_at|date:"d.M.Y"|lower }}
</small>
</p>
<p>
{% if post.image %}
<img src="{{ post.image.url }}" class="w-100" alt="{{ post.title|safe }}" />
{% else %}
<img src="{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}" class="w-100" alt="{{ post.title|safe }}" />
{% endif %}
</p> </p>
<p>{% if page.image %}
<img src="{{ page.image.url }}" class="w-100" alt="{{ page.image|striptags|unescape|safe }}"/>
{% else %}<img src="{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}" class="w-100" alt="{{ page.image|striptags|unescape|safe }}"/>
{% endif %}</p>
</div> </div>
{# Правая колонка: Контент #} {# Правая колонка: Контент #}
<div class="col-lg-10 border-start ps-lg-4 post-page-content"> <div class="col-lg-10 border-start ps-lg-4 post-page-content">
<h1 class="display-4 mb-4">{{ page.title|safe }}</h1> <h1 class="display-4 mb-4">{{ page.title|safe }}</h1>
{% if page.excerpt %} {% if page.excerpt %}
<div class="lead bg-secondary bg-opacity-10 p-3 rounded"> <div class="lead bg-secondary bg-opacity-10 p-3 rounded">
{{ page.excerpt|safe }} {{ page.excerpt|safe }}
</div>
{% endif %}
<div class="page-content mt-4">
{{ page.content|safe }}
</div> </div>
{% endif %}
<div class="page-content mt-4">
{{ page.content|safe }}
</div>
</div> </div>
</div> </div>

View File

@@ -1,58 +1,53 @@
{% extends 'typograph/base.html' %} {% extends 'typograph/base.html' %}
{% load static %} {% load static %}
{% load typograph_extras %}
{% block title %}{{ post.seo_title|default:post.title }} — ETPGRF{% endblock %} {% block title %}{% if post.seo_title %}{{ post.seo_title }}{% else %}{{ post.title|striptags|unescape|safe }}{% endif %} — ETPGRF{% endblock %}
{% block description %}{{ post.seo_description|default:post.excerpt|default:post.content|striptags|truncatechars:160 }}{% endblock %} {% block description %}{% if post.seo_description %}{{ post.seo_description }}{% else %}{{ post.excerpt|striptags|unescape|safe|truncatechars:160 }}{% endif %}{% endblock %}
{% block og_title %}{{ post.seo_title|default:post.title }}{% endblock %} {% block keywords %}{% if post.seo_keywords %}{{ post.seo_keywords }}{% else %}типограф, типографика, блог типограф, онлайн типограф, подготовка текста для веба, html типограф, неразрывные пробелы, кавычки елочки, длинное тире, очистка текста от мусора, интернет верстка, муравьев, лебедев{% endif %}{% endblock %}
{% block og_description %}{{ post.seo_description|default:post.excerpt|default:post.content|striptags|truncatechars:160 }}{% endblock %}
{% block og_title %}{% if post.seo_title %}{{ post.seo_title }}{% else %}{{ post.title|striptags|unescape|safe }}{% endif %}{% endblock %}
{% block og_description %}{% if post.seo_description %}{{ post.seo_description }}{% else %}{{ post.excerpt|striptags|unescape|safe|truncatechars:160 }}{% endif %}{% endblock %}
{% block og_image %}{% if post.image %}{{ request.scheme }}://{{ request.get_host }}{{ post.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %} {% block og_image %}{% if post.image %}{{ request.scheme }}://{{ request.get_host }}{{ post.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %}
{% block twitter_title %}{{ post.seo_title|default:post.title }}{% endblock %} {% block twitter_title %}{% if post.seo_title %}{{ post.seo_title }}{% else %}{{ post.title|striptags|unescape|safe }}{% endif %}{% endblock %}
{% block twitter_description %}{{ post.seo_description|default:post.excerpt|default:post.content|striptags|truncatechars:160 }}{% endblock %} {% block twitter_description %}{% if post.seo_description %}{{ post.seo_description }}{% else %}{{ post.excerpt|striptags|unescape|safe|truncatechars:160 }}{% endif %}{% endblock %}
{% block twitter_image %}{% if post.image %}{{ request.scheme }}://{{ request.get_host }}{{ post.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %} {% block twitter_image %}{% if post.image %}{{ request.scheme }}://{{ request.get_host }}{{ post.image.url }}{% else %}{{ request.scheme }}://{{ request.get_host }}{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}{% endif %}{% endblock %}
{% block content %} {% block content %}
<div class="row"> <div class="row">
{# Левая колонка: Дата и Картинка #} {# Левая колонка: Дата и Картинка #}
<div class="col-lg-2 align-self-start text-end mb-4"> <div class="col-lg-2 align-self-start text-end mb-4">
<p class="small align-self-end"> <p class="small align-self-end">
<small class="bg-secondary bg-opacity-10 p-2 text-nowrap"> <small class="bg-secondary bg-opacity-10 p-2 text-nowrap">
{{ post.published_at|date:"d.M.Y"|lower }} {{ post.published_at|date:"d.M.Y"|lower }}
</small> </small>
</p>
<p>
{% if post.image %}
<img src="{{ post.image.url }}" class="w-100" alt="{{ post.title }}" />
{% else %}
<img src="{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}" class="w-100" alt="{{ post.title }}" />
{% endif %}
</p> </p>
<p>{% if post.image %}
<img src="{{ post.image.url }}" class="w-100" alt="{{ post.title|striptags|unescape|safe }}"/>
{% else %}<img src="{% static 'img/etpgrf-logo-for-fb-vk-x.gif' %}" class="w-100" alt="{{ post.title|striptags|unescape|safe }}"/>
{% endif %}</p>
<div class="d-none d-lg-block mt-5"> <div class="d-none d-lg-block mt-5">
<a href="{% url 'blog:post_list' %}" class="btn btn-sm btn-outline-secondary w-100">&larr; В блог</a> <a href="{% url 'blog:post_list' %}" class="btn btn-sm btn-outline-secondary w-100">&larr; В блог</a>
</div> </div>
</div> </div>
{# Правая колонка: Контент #} {# Правая колонка: Контент #}
<div class="col-lg-10 border-start ps-lg-4 post-page-content"> <div class="col-lg-10 border-start ps-lg-4 post-page-content">
<h1 class="display-4 mb-4">{{ post.title|safe }}</h1>
<h1 class="display-4 mb-4">{{ post.title }}</h1> {% if post.excerpt %}<div class="lead bg-secondary bg-opacity-10 p-3 rounded">
{{ post.excerpt|safe }}
</div>{% endif %}
{% if post.excerpt %} <div class="post-content mt-4">
<p class="lead bg-secondary bg-opacity-10 p-3 rounded"> {{ post.content|safe }}
{{ post.excerpt|linebreaksbr }} </div>
</p>
{% endif %}
<div class="post-content mt-4"> <div class="d-lg-none mt-5 border-top pt-3">
{{ post.content|safe }} <a href="{% url 'blog:post_list' %}" class="btn btn-outline-secondary">&larr; Назад к списку статей</a>
</div> </div>
<div class="d-lg-none mt-5 border-top pt-3">
<a href="{% url 'blog:post_list' %}" class="btn btn-outline-secondary">&larr; Назад к списку статей</a>
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -1,5 +1,6 @@
from django import template from django import template
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
import html
register = template.Library() register = template.Library()
@@ -40,6 +41,25 @@ def humanize_num(value):
formatted = formatted.replace(",", "&thinsp;").replace(".", ",") formatted = formatted.replace(",", "&thinsp;").replace(".", ",")
return mark_safe(f"{formatted}{suffix}") return mark_safe(f"{formatted}{suffix}")
except (ValueError, TypeError): except (ValueError, TypeError):
return value return value
@register.filter(name='unescape')
def unescape_filter(value):
"""
Декодирует HTML-сущности (&nbsp; -> ' ', &mdash; -> —)
и удаляет лишние пробелы и переводы строк.
Полезно для мета-тегов (title, description, og:title).
"""
if not value:
return ""
# 1. Декодируем сущности
text = html.unescape(str(value))
# 2. Удаляем лишние пробелы и переводы строк
# split() без аргументов разбивает по любым пробельным символам (\n, \t, space)
# " ".join(...) собирает обратно через один пробел
return " ".join(text.split())