Дизайн-фиксы: - Перенесены картинки из старого WP в public/wp-content/uploads/ (header_bg.gif + 3 размера NY-baner.png 2014/12). migrate-wp.mjs обновлён: корректно обрабатывает <a><img></a>, переписывает абсолютные URL anotherreflections.ru/wp-content/... в относительные - Description в frontmatter теперь чистый plain text — без markdown-разметки - Слаги 11/95/152 → kto-my, s-23-fevralya-2011, s-nastupayushhim-novym-2012-godom - Hero-метрика: «N лет онлайн» → «с 2006 года» (последний пост 2015, активной жизни «20 лет» нет) - Drop cap (буквица) — только для постов длиннее 240 символов (короткие посты раньше выглядели обрезанными) Аналитика и конфиденциальность: - Яндекс.Метрика (counter 13938862, webvisor) и Google gtag (GT-PH39R3X) перенесены со старого WP - Cookie consent banner — самописный, без зависимостей: счётчики грузятся только после явного «Принять». Выбор хранится в localStorage + cookie ar-consent на 12 месяцев. Уведомление в духе 152-ФЗ - /privacy/ — полная политика конфиденциальности: что собираем (через Метрику и GA), для чего, как cookies устроены, права пользователя, контакт для запросов на удаление - В футере добавлены ссылки «Политика конфиденциальности» и «Контакты» - sitemap.txt + llms.txt включают /privacy/
74 lines
2.9 KiB
Plaintext
74 lines
2.9 KiB
Plaintext
---
|
||
// Минимальный self-hosted cookie consent под 152-ФЗ:
|
||
// — баннер показывается до явного выбора (cookie `ar-consent`)
|
||
// — «Принять» → активирует все <script type="text/plain" data-cookieconsent="statistics">
|
||
// — «Только необходимые» → ничего не активирует, баннер исчезает
|
||
// — выбор хранится в localStorage и cookie на 12 месяцев
|
||
---
|
||
<div id="cookie-consent" class="cookie-consent" hidden>
|
||
<div class="cookie-text">
|
||
<p>
|
||
Мы используем cookies и сервисы статистики (Яндекс.Метрика, Google Analytics),
|
||
чтобы понимать, как вы пользуетесь сайтом, и делать его лучше.
|
||
Подробнее — в <a href="/privacy/">политике конфиденциальности</a>.
|
||
</p>
|
||
</div>
|
||
<div class="cookie-actions">
|
||
<button type="button" class="cookie-btn cookie-btn-secondary" data-cc-deny>Только необходимые</button>
|
||
<button type="button" class="cookie-btn cookie-btn-primary" data-cc-accept>Принять</button>
|
||
</div>
|
||
</div>
|
||
<script is:inline>
|
||
(function () {
|
||
const KEY = 'ar-consent';
|
||
const banner = document.getElementById('cookie-consent');
|
||
if (!banner) return;
|
||
|
||
const activate = () => {
|
||
document.querySelectorAll('script[type="text/plain"][data-cookieconsent="statistics"]').forEach((tpl) => {
|
||
const s = document.createElement('script');
|
||
for (const a of tpl.attributes) {
|
||
if (a.name === 'type' || a.name === 'data-cookieconsent') continue;
|
||
s.setAttribute(a.name, a.value);
|
||
}
|
||
s.text = tpl.textContent || '';
|
||
tpl.parentNode.insertBefore(s, tpl);
|
||
tpl.parentNode.removeChild(tpl);
|
||
});
|
||
};
|
||
|
||
const setConsent = (value) => {
|
||
try { localStorage.setItem(KEY, value); } catch {}
|
||
const exp = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toUTCString();
|
||
document.cookie = `${KEY}=${value}; expires=${exp}; path=/; SameSite=Lax`;
|
||
};
|
||
|
||
const current = (() => {
|
||
try {
|
||
const ls = localStorage.getItem(KEY);
|
||
if (ls) return ls;
|
||
} catch {}
|
||
const m = document.cookie.match(/(?:^|; )ar-consent=([^;]+)/);
|
||
return m ? decodeURIComponent(m[1]) : null;
|
||
})();
|
||
|
||
if (current === 'accept') {
|
||
activate();
|
||
} else if (current === 'deny') {
|
||
// ничего не делаем — статистика не активируется
|
||
} else {
|
||
banner.hidden = false;
|
||
}
|
||
|
||
banner.querySelector('[data-cc-accept]')?.addEventListener('click', () => {
|
||
setConsent('accept');
|
||
banner.hidden = true;
|
||
activate();
|
||
});
|
||
banner.querySelector('[data-cc-deny]')?.addEventListener('click', () => {
|
||
setConsent('deny');
|
||
banner.hidden = true;
|
||
});
|
||
})();
|
||
</script>
|