From 4ad88a327e8731ebf604c198f0087ebb097e4ce3 Mon Sep 17 00:00:00 2001 From: Andrew Doering Date: Thu, 19 Feb 2026 17:21:25 +0100 Subject: [PATCH] feat: add GDPR cookie consent banner (#1216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add GDPR cookie consent banner Add a GDPR-compliant cookie consent banner that gates analytics (Google Analytics) and functional cookies (comments) until user consent is given. Features: - Theme-consistent styling using CSS variables (light/dark mode) - Settings panel with category toggles (necessary, analytics, functional) - Consent stored in cookie for 365 days - Google Analytics only loads after analytics consent - Comments only load after functional consent - Translations for all 32 supported languages - Accessible with proper ARIA attributes and focus management Configuration in hugo.yaml: params: cookies: enabled: true categories: analytics: true functional: true When cookies.enabled is false, scripts load normally without consent gating. Closes #412 * refactor: move consent-gated GA to cookies/analytics.html Move Google Analytics consent logic to avoid shadowing Hugo's internal `_internal/google_analytics.html` template. Changes: - Rename google_analytics.html → cookies/analytics.html - Update head.html to conditionally load: - cookies.enabled=true: cookies/analytics.html (consent-gated) - cookies.enabled=false: Hugo's _internal/google_analytics.html - Align cookies/analytics.html with Hugo's internal template: - Support Privacy.GoogleAnalytics.Disable setting - Support Privacy.GoogleAnalytics.RespectDoNotTrack setting - Add UA- prefix deprecation warning Note: Custom JS is required for consent-gated GA because Hugo templates render at build time, but consent happens at runtime. We cannot call Hugo's internal template after the user grants consent - we must dynamically inject the GA script via JavaScript. * style: indent cookies/analytics.html * refactor: don't use default, put default configurations in params.toml * fix: don't use `description` as translation key because it's reserved and will throw error * fix: remove footer/components/custom-font.html call * fix: banner showSettings key * style: indent comments/include * Add missing article.alert translation back * style: format i18n toml files * style: indent head/head.html * style adjustment * style: add missing - * style: format demo/config/params.toml * style: remove redundant comments from cookies.scss * style: update box-shadow for cookie banner content --------- Co-authored-by: delize <4028612+delize@users.noreply.github.com> Co-authored-by: Jimmy Cai --- assets/scss/partials/cookies.scss | 199 ++++++++++++++++++++ assets/scss/style.scss | 1 + assets/ts/cookies.ts | 221 +++++++++++++++++++++++ config/_default/params.toml | 10 + demo/config/_default/params.toml | 9 + i18n/ar.toml | 24 +++ i18n/be.toml | 24 +++ i18n/bg.toml | 24 +++ i18n/bn.toml | 34 +++- i18n/ca.toml | 24 +++ i18n/cs.toml | 24 +++ i18n/de.toml | 24 +++ i18n/el.toml | 24 +++ i18n/en.toml | 24 +++ i18n/es.toml | 24 +++ i18n/fa.toml | 24 +++ i18n/fr.toml | 24 +++ i18n/hi.toml | 24 +++ i18n/hu.toml | 24 +++ i18n/id.toml | 24 +++ i18n/it.toml | 24 +++ i18n/ja.toml | 24 +++ i18n/ko.toml | 24 +++ i18n/nl.toml | 24 +++ i18n/oc.toml | 24 +++ i18n/pl.toml | 24 +++ i18n/pt-br.toml | 24 +++ i18n/pt-pt.toml | 24 +++ i18n/ru.toml | 24 +++ i18n/sk.toml | 24 +++ i18n/th.toml | 24 +++ i18n/tr.toml | 24 +++ i18n/uk.toml | 24 +++ i18n/vi.toml | 24 +++ i18n/zh-hant-hk.toml | 24 +++ i18n/zh-hant-tw.toml | 24 +++ i18n/zh.toml | 24 +++ layouts/_partials/comments/include.html | 46 ++++- layouts/_partials/cookies/analytics.html | 50 +++++ layouts/_partials/cookies/banner.html | 68 +++++++ layouts/_partials/cookies/include.html | 9 + layouts/_partials/footer/include.html | 3 +- layouts/_partials/head/head.html | 7 +- 43 files changed, 1393 insertions(+), 8 deletions(-) create mode 100644 assets/scss/partials/cookies.scss create mode 100644 assets/ts/cookies.ts create mode 100644 layouts/_partials/cookies/analytics.html create mode 100644 layouts/_partials/cookies/banner.html create mode 100644 layouts/_partials/cookies/include.html diff --git a/assets/scss/partials/cookies.scss b/assets/scss/partials/cookies.scss new file mode 100644 index 0000000..9046bee --- /dev/null +++ b/assets/scss/partials/cookies.scss @@ -0,0 +1,199 @@ +.cookie-banner { + position: fixed; + bottom: 0; + left: 0; + right: 0; + z-index: 9999; + padding: var(--container-padding); + + &[aria-hidden="true"] { + display: none; + } +} + +.cookie-banner__content { + max-width: 900px; + margin: 0 auto; + background: var(--card-background); + border-radius: var(--card-border-radius); + box-shadow: var(--shadow-l3); + padding: var(--card-padding); + display: flex; + flex-direction: column; + gap: 15px; + + @include respond(md) { + flex-direction: row; + flex-wrap: wrap; + align-items: center; + gap: 20px; + } +} + +.cookie-banner__text { + flex: 1; + min-width: 200px; + + strong { + display: block; + color: var(--card-text-color-main); + font-size: 1.6rem; + margin-bottom: 5px; + } + + p { + color: var(--card-text-color-secondary); + font-size: 1.4rem; + line-height: 1.6; + margin: 0; + } +} + +.cookie-banner__actions { + display: flex; + gap: 10px; + flex-shrink: 0; +} + +.cookie-banner__settings-link { + width: auto; + align-self: flex-start; + background: none; + border: none; + color: var(--accent-color); + font-size: 1.3rem; + cursor: pointer; + padding: 5px; + + &:hover { + text-decoration: underline; + } + + @include respond(md) { + width: auto; + margin-left: auto; + align-self: center; + } +} + +.cookie-btn { + padding: 10px 20px; + border-radius: var(--tag-border-radius); + font-size: 1.4rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + border: none; + + &--primary { + background: var(--accent-color); + color: var(--accent-color-text); + + &:hover { + background: var(--accent-color-darker); + } + } + + &--secondary { + background: transparent; + color: var(--card-text-color-main); + border: 1.5px solid var(--card-separator-color); + + &:hover { + background: var(--card-background-selected); + } + } +} + +// Cookie settings panel +.cookie-settings { + padding-top: 20px; + border-top: 1.5px solid var(--card-separator-color); + + &[aria-hidden="true"] { + display: none; + } + + h3 { + color: var(--card-text-color-main); + font-size: 1.6rem; + margin: 0 0 15px 0; + } + + &__actions { + display: flex; + justify-content: flex-end; + gap: 10px; + margin-top: 20px; + } +} + +.cookie-category { + padding: 15px 0; + border-bottom: 1px solid var(--card-separator-color); + + &:last-of-type { + border-bottom: none; + } + + label { + display: flex; + align-items: center; + gap: 10px; + cursor: pointer; + + input[type="checkbox"] { + width: 18px; + height: 18px; + accent-color: var(--accent-color); + cursor: pointer; + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + } + + strong { + color: var(--card-text-color-main); + font-size: 1.5rem; + } + } + + p { + color: var(--card-text-color-secondary); + font-size: 1.3rem; + margin: 8px 0 0 28px; + line-height: 1.5; + } +} + +// Footer link for reopening settings +.cookie-settings-link { + display: inline-block; + color: var(--body-text-color); + font-size: 1.2rem; + cursor: pointer; + background: none; + border: none; + padding: 0; + + &:hover { + color: var(--accent-color); + text-decoration: underline; + } +} + +// Comments placeholder when consent not given +.consent-placeholder { + background: var(--card-background); + border-radius: var(--card-border-radius); + padding: var(--card-padding); + text-align: center; + color: var(--card-text-color-secondary); + font-size: 1.4rem; + + p { + margin: 0 0 15px 0; + } +} \ No newline at end of file diff --git a/assets/scss/style.scss b/assets/scss/style.scss index e50d400..2f4b369 100644 --- a/assets/scss/style.scss +++ b/assets/scss/style.scss @@ -23,6 +23,7 @@ @import "partials/layout/list.scss"; @import "partials/layout/404.scss"; @import "partials/layout/search.scss"; +@import "partials/cookies.scss"; @import "general.scss"; @import "custom.scss"; diff --git a/assets/ts/cookies.ts b/assets/ts/cookies.ts new file mode 100644 index 0000000..a4922bf --- /dev/null +++ b/assets/ts/cookies.ts @@ -0,0 +1,221 @@ +interface ConsentState { + necessary: boolean; + analytics: boolean; + functional: boolean; + timestamp: number; +} + +class CookieConsent { + private static COOKIE_NAME = 'cookie_consent'; + private static COOKIE_DAYS = 365; + + private state: ConsentState | null = null; + private banner: HTMLElement | null = null; + private settingsPanel: HTMLElement | null = null; + + constructor() { + this.banner = document.getElementById('cookie-consent-banner'); + this.settingsPanel = document.getElementById('cookie-settings-panel'); + + this.state = this.loadState(); + + if (!this.state && this.banner) { + this.showBanner(); + } + + this.bindEvents(); + this.dispatchConsentEvent(); + } + + private loadState(): ConsentState | null { + const cookie = document.cookie + .split('; ') + .find(row => row.startsWith(CookieConsent.COOKIE_NAME + '=')); + + if (!cookie) return null; + + try { + return JSON.parse(decodeURIComponent(cookie.split('=')[1])); + } catch { + return null; + } + } + + private saveState(): void { + if (!this.state) return; + + const expires = new Date(); + expires.setDate(expires.getDate() + CookieConsent.COOKIE_DAYS); + + document.cookie = `${CookieConsent.COOKIE_NAME}=${encodeURIComponent(JSON.stringify(this.state))}; expires=${expires.toUTCString()}; path=/; SameSite=Lax`; + } + + private showBanner(): void { + if (this.banner) { + this.banner.removeAttribute('aria-hidden'); + } + } + + private hideBanner(): void { + if (this.banner) { + // Blur any focused element inside the banner before hiding + const activeElement = document.activeElement as HTMLElement; + if (activeElement && this.banner.contains(activeElement)) { + activeElement.blur(); + } + this.banner.setAttribute('aria-hidden', 'true'); + } + this.hideSettings(); + } + + private showSettings(): void { + if (this.settingsPanel) { + this.settingsPanel.removeAttribute('aria-hidden'); + + // Restore checkbox states from current state or defaults + const checkboxes = this.settingsPanel.querySelectorAll('input[data-cookie-category]'); + checkboxes.forEach((cb) => { + const input = cb as HTMLInputElement; + const category = input.dataset.cookieCategory as keyof ConsentState; + if (category && this.state && typeof this.state[category] === 'boolean') { + input.checked = this.state[category] as boolean; + } else { + input.checked = false; + } + }); + } + } + + private hideSettings(): void { + if (this.settingsPanel) { + // Blur any focused element inside the settings panel before hiding + const activeElement = document.activeElement as HTMLElement; + if (activeElement && this.settingsPanel.contains(activeElement)) { + activeElement.blur(); + } + this.settingsPanel.setAttribute('aria-hidden', 'true'); + } + } + + private bindEvents(): void { + document.addEventListener('click', (e) => { + const target = e.target as HTMLElement; + const action = target.dataset.cookieAction; + + if (!action) return; + + switch (action) { + case 'accept': + this.acceptAll(); + break; + case 'deny': + this.denyAll(); + break; + case 'settings': + this.showSettings(); + break; + case 'save': + this.saveSettings(); + break; + case 'cancel': + this.hideSettings(); + break; + case 'reopen': + this.showBanner(); + break; + } + }); + } + + private acceptAll(): void { + this.state = { + necessary: true, + analytics: true, + functional: true, + timestamp: Date.now() + }; + this.saveState(); + this.hideBanner(); + this.dispatchConsentEvent(); + } + + private denyAll(): void { + this.state = { + necessary: true, + analytics: false, + functional: false, + timestamp: Date.now() + }; + this.saveState(); + this.hideBanner(); + this.dispatchConsentEvent(); + } + + private saveSettings(): void { + const checkboxes = document.querySelectorAll('input[data-cookie-category]'); + + this.state = { + necessary: true, + analytics: false, + functional: false, + timestamp: Date.now() + }; + + checkboxes.forEach((cb) => { + const input = cb as HTMLInputElement; + const category = input.dataset.cookieCategory as keyof ConsentState; + if (category && category in this.state!) { + (this.state as any)[category] = input.checked; + } + }); + + this.saveState(); + this.hideBanner(); + this.dispatchConsentEvent(); + } + + private dispatchConsentEvent(): void { + const event = new CustomEvent('onCookieConsentChange', { + detail: this.state + }); + window.dispatchEvent(event); + + // Set data attributes on document for CSS-based control + if (this.state) { + document.documentElement.dataset.consentAnalytics = String(this.state.analytics); + document.documentElement.dataset.consentFunctional = String(this.state.functional); + } + } + + // Public API + public hasConsent(category: keyof Omit): boolean { + if (!this.state) return false; + return this.state[category] ?? false; + } + + public getState(): ConsentState | null { + return this.state; + } + + public reopenBanner(): void { + this.showBanner(); + } +} + +// Export for module usage +export default CookieConsent; + +// Initialize when DOM is ready and expose globally +declare global { + interface Window { + cookieConsent: CookieConsent; + } +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', () => { + window.cookieConsent = new CookieConsent(); + }); +} else { + window.cookieConsent = new CookieConsent(); +} diff --git a/config/_default/params.toml b/config/_default/params.toml index 7783440..7c31901 100644 --- a/config/_default/params.toml +++ b/config/_default/params.toml @@ -77,6 +77,16 @@ SortBy = "default" [imageProcessing.content] enabled = true +# GDPR Cookie Consent Configuration +# When enabled, analytics and functional cookies require user consent +[cookies] + enabled = false + showSettings = true + + [cookies.categories] + analytics = true + functional = true + [comments] enabled = true provider = "disqus" diff --git a/demo/config/_default/params.toml b/demo/config/_default/params.toml index cd54673..cee76de 100644 --- a/demo/config/_default/params.toml +++ b/demo/config/_default/params.toml @@ -28,3 +28,12 @@ favicon = "img/avatar.png" # See complete configuration in config/_default/params.toml enabled = true provider = "disqus" + +# GDPR Cookie Consent Configuration +# When enabled, analytics and functional cookies require user consent +[cookies] + enabled = true + + [cookies.categories] + analytics = true + functional = true diff --git a/i18n/ar.toml b/i18n/ar.toml index d7b3b6f..b4c58d4 100644 --- a/i18n/ar.toml +++ b/i18n/ar.toml @@ -52,3 +52,27 @@ darkMode = "الوضع الداكن" [footer] builtWith = "مبني باستخدام {{ .Generator }}" designedBy = "قالب {{ .Theme }} مصمم من {{ .DesignedBy }}" + +[cookies] + title = "موافقة ملفات تعريف الارتباط" + text = "نستخدم ملفات تعريف الارتباط لتحسين تجربة التصفح وتحليل حركة المرور على الموقع." + acceptAll = "قبول الكل" + deny = "رفض" + managePreferences = "إدارة التفضيلات" + settingsTitle = "تفضيلات ملفات تعريف الارتباط" + savePreferences = "حفظ التفضيلات" + cancel = "إلغاء" + footerLink = "إعدادات ملفات تعريف الارتباط" + commentsDisabled = "التعليقات معطلة حتى تقبل ملفات تعريف الارتباط الوظيفية." + + [cookies.necessary] + title = "ضروري" + text = "ملفات تعريف الارتباط هذه مطلوبة لعمل الموقع ولا يمكن تعطيلها." + + [cookies.analytics] + title = "التحليلات" + text = "تساعدنا ملفات تعريف الارتباط هذه على فهم كيفية تفاعل الزوار مع موقعنا." + + [cookies.functional] + title = "وظيفي" + text = "تتيح ملفات تعريف الارتباط هذه ميزات مثل التعليقات والمحتوى المضمن." diff --git a/i18n/be.toml b/i18n/be.toml index 020e2c8..2df93bb 100644 --- a/i18n/be.toml +++ b/i18n/be.toml @@ -50,3 +50,27 @@ darkMode = "Цёмны рэжым" [footer] builtWith = "Створана пры дапамозе {{ .Generator }}" designedBy = "Тэма {{ .Theme }}, дызайн {{ .DesignedBy }}" + +[cookies] + title = "Згода на файлы cookie" + text = "Мы выкарыстоўваем файлы cookie для паляпшэння вашага досведу і аналізу трафіку сайта." + acceptAll = "Прыняць усё" + deny = "Адхіліць" + managePreferences = "Кіраваць налады" + settingsTitle = "Налады файлаў cookie" + savePreferences = "Захаваць налады" + cancel = "Скасаваць" + footerLink = "Налады файлаў cookie" + commentsDisabled = "Каментары адключаны, пакуль вы не прымеце функцыянальныя файлы cookie." + + [cookies.necessary] + title = "Неабходныя" + text = "Гэтыя файлы cookie неабходныя для працы сайта і не могуць быць адключаны." + + [cookies.analytics] + title = "Аналітыка" + text = "Гэтыя файлы cookie дапамагаюць нам зразумець, як наведвальнікі ўзаемадзейнічаюць з нашым сайтам." + + [cookies.functional] + title = "Функцыянальныя" + text = "Гэтыя файлы cookie ўключаюць такія функцыі, як каментары і ўбудаваны кантэнт." diff --git a/i18n/bg.toml b/i18n/bg.toml index c455d0e..8b618c1 100644 --- a/i18n/bg.toml +++ b/i18n/bg.toml @@ -52,3 +52,27 @@ darkMode = "Тъмен Режим" [footer] builtWith = "Създадено с {{ .Generator }}" designedBy = "Тема {{ .Theme }} създадена от {{ .DesignedBy }}" + +[cookies] + title = "Съгласие за бисквитки" + text = "Използваме бисквитки, за да подобрим вашето изживяване и да анализираме трафика на сайта." + acceptAll = "Приемане на всички" + deny = "Откажи" + managePreferences = "Управление на предпочитанията" + settingsTitle = "Предпочитания за бисквитки" + savePreferences = "Запазване на предпочитанията" + cancel = "Отказ" + footerLink = "Настройки на бисквитките" + commentsDisabled = "Коментарите са деактивирани, докато не приемете функционални бисквитки." + + [cookies.necessary] + title = "Необходими" + text = "Тези бисквитки са необходими за функционирането на уебсайта и не могат да бъдат деактивирани." + + [cookies.analytics] + title = "Анализи" + text = "Тези бисквитки ни помагат да разберем как посетителите взаимодействат с нашия уебсайт." + + [cookies.functional] + title = "Функционални" + text = "Тези бисквитки активират функции като коментари и вградено съдържание." diff --git a/i18n/bn.toml b/i18n/bn.toml index 2d1046e..fbac542 100644 --- a/i18n/bn.toml +++ b/i18n/bn.toml @@ -15,12 +15,12 @@ darkMode = "ডার্ক মোড" [article] back = "পেছনে" tableOfContents = "সূচিপত্র" - relatedContent = "সম্পর্কিত বিষয়বস্তু" + relatedContent = "সম্পর্কিত বিষয়বস্তু" lastUpdatedOn = "সর্বশেষ আপডেট করা হয়েছে" [article.readingTime] - one = "{{ .Count }} মিনিটে পড়া যাবে" - other = "{{ .Count }} মিনিটে পড়া যাবে" + one = "{{ .Count }} মিনিটে পড়া যাবে" + other = "{{ .Count }} মিনিটে পড়া যাবে" [article.alert] note = "টীকা" @@ -30,7 +30,7 @@ darkMode = "ডার্ক মোড" caution = "সাবধানতা" [notFound] - title = "পাওয়া যায়নি" + title = "পাওয়া যায়নি" subtitle = "এই পাতাটি বিদ্যমান নেই" [widget] @@ -50,5 +50,29 @@ darkMode = "ডার্ক মোড" resultTitle = "#PAGES_COUNT পাতা (#TIME_SECONDS সেকেন্ড)" [footer] - builtWith = "{{ .Generator }} দিয়ে নির্মিত" + builtWith = "{{ .Generator }} দিয়ে নির্মিত" designedBy = "থিম {{ .Theme }} ডিজাইন করেছেন {{ .DesignedBy }}" + +[cookies] + title = "কুকি সম্মতি" + text = "আমরা আপনার ব্রাউজিং অভিজ্ঞতা উন্নত করতে এবং সাইট ট্রাফিক বিশ্লেষণ করতে কুকি ব্যবহার করি।" + acceptAll = "সবগুলো গ্রহণ করুন" + deny = "প্রত্যাখ্যান" + managePreferences = "পছন্দসমূহ পরিচালনা করুন" + settingsTitle = "কুকি পছন্দসমূহ" + savePreferences = "পছন্দসমূহ সংরক্ষণ করুন" + cancel = "বাতিল" + footerLink = "কুকি সেটিংস" + commentsDisabled = "আপনি কার্যকরী কুকি গ্রহণ না করা পর্যন্ত মন্তব্য অক্ষম করা আছে।" + + [cookies.necessary] + title = "প্রয়োজনীয়" + text = "এই কুকিগুলি ওয়েবসাইট কাজ করার জন্য প্রয়োজনীয় এবং নিষ্ক্রিয় করা যায় না।" + + [cookies.analytics] + title = "বিশ্লেষণ" + text = "এই কুকিগুলি আমাদের বুঝতে সাহায্য করে যে দর্শকরা কীভাবে আমাদের ওয়েবসাইটের সাথে ইন্টারঅ্যাক্ট করে।" + + [cookies.functional] + title = "কার্যকরী" + text = "এই কুকিগুলি মন্তব্য এবং এম্বেড করা বিষয়বস্তুর মতো বৈশিষ্ট্যগুলি সক্ষম করে." diff --git a/i18n/ca.toml b/i18n/ca.toml index 3588cda..bc0d705 100644 --- a/i18n/ca.toml +++ b/i18n/ca.toml @@ -52,3 +52,27 @@ darkMode = "Mode fosc" [footer] builtWith = "Creat amb {{ .Generator }}" designedBy = "Tema {{ .Theme }} dissenyat per {{ .DesignedBy }}" + +[cookies] + title = "Consentiment de galetes" + text = "Utilitzem galetes per millorar la vostra experiència de navegació i analitzar el trànsit del lloc." + acceptAll = "Acceptar-ho tot" + deny = "Denegar" + managePreferences = "Gestionar preferències" + settingsTitle = "Preferències de galetes" + savePreferences = "Desar preferències" + cancel = "Cancel·lar" + footerLink = "Configuració de galetes" + commentsDisabled = "Els comentaris estan desactivats fins que accepteu les galetes funcionals." + + [cookies.necessary] + title = "Necessàries" + text = "Aquestes galetes són necessàries perquè el lloc web funcioni i no es poden desactivar." + + [cookies.analytics] + title = "Analítiques" + text = "Aquestes galetes ens ajuden a entendre com els visitants interactuen amb el nostre lloc web." + + [cookies.functional] + title = "Funcionals" + text = "Aquestes galetes habiliten funcionalitats com comentaris i contingut incrustat." diff --git a/i18n/cs.toml b/i18n/cs.toml index 17a9ae4..85fc822 100644 --- a/i18n/cs.toml +++ b/i18n/cs.toml @@ -52,3 +52,27 @@ darkMode = "Tmavý režim" [footer] builtWith = "Vytvořeno pomocí {{ .Generator }}" designedBy = "Šablona {{ .Theme }} od {{ .DesignedBy }}" + +[cookies] + title = "Souhlas s cookies" + text = "Používáme cookies ke zlepšení vašeho prohlížení a analýze návštěvnosti webu." + acceptAll = "Přijmout vše" + deny = "Odmítnout" + managePreferences = "Spravovat předvolby" + settingsTitle = "Předvolby cookies" + savePreferences = "Uložit předvolby" + cancel = "Zrušit" + footerLink = "Nastavení cookies" + commentsDisabled = "Komentáře jsou zakázány, dokud nepřijmete funkční cookies." + + [cookies.necessary] + title = "Nutné" + text = "Tyto cookies jsou nutné pro fungování webu a nelze je zakázat." + + [cookies.analytics] + title = "Analytické" + text = "Tyto cookies nám pomáhají pochopit, jak návštěvníci interagují s naším webem." + + [cookies.functional] + title = "Funkční" + text = "Tyto cookies umožňují funkce jako komentáře a vložený obsah." diff --git a/i18n/de.toml b/i18n/de.toml index 5d20565..6e253ee 100644 --- a/i18n/de.toml +++ b/i18n/de.toml @@ -52,3 +52,27 @@ darkMode = "Dunkler Modus" [footer] builtWith = "Erstellt mit {{ .Generator }}" designedBy = "Theme {{ .Theme }} gestaltet von {{ .DesignedBy }}" + +[cookies] + title = "Cookie-Einwilligung" + text = "Wir verwenden Cookies, um Ihr Surferlebnis zu verbessern und den Website-Traffic zu analysieren." + acceptAll = "Alle akzeptieren" + deny = "Ablehnen" + managePreferences = "Einstellungen verwalten" + settingsTitle = "Cookie-Einstellungen" + savePreferences = "Einstellungen speichern" + cancel = "Abbrechen" + footerLink = "Cookie-Einstellungen" + commentsDisabled = "Kommentare sind deaktiviert, bis Sie funktionale Cookies akzeptieren." + + [cookies.necessary] + title = "Notwendig" + text = "Diese Cookies sind für die Funktion der Website erforderlich und können nicht deaktiviert werden." + + [cookies.analytics] + title = "Analyse" + text = "Diese Cookies helfen uns zu verstehen, wie Besucher mit unserer Website interagieren." + + [cookies.functional] + title = "Funktional" + text = "Diese Cookies ermöglichen Funktionen wie Kommentare und eingebettete Inhalte." diff --git a/i18n/el.toml b/i18n/el.toml index 31c7576..c4bbd93 100644 --- a/i18n/el.toml +++ b/i18n/el.toml @@ -49,3 +49,27 @@ darkMode = "Σκοτεινό θέμα" [footer] builtWith = "Δημιουργήθηκε με τη χρήση {{ .Generator }}" designedBy = "Το θέμα {{ .Theme }} σχεδιάστηκε από το {{ .DesignedBy }}" + +[cookies] + title = "Συγκατάθεση για cookies" + text = "Χρησιμοποιούμε cookies για να βελτιώσουμε την εμπειρία περιήγησής σας και να αναλύσουμε την επισκεψιμότητα του ιστότοπου." + acceptAll = "Αποδοχή όλων" + deny = "Άρνηση" + managePreferences = "Διαχείριση προτιμήσεων" + settingsTitle = "Προτιμήσεις cookies" + savePreferences = "Αποθήκευση προτιμήσεων" + cancel = "Ακύρωση" + footerLink = "Ρυθμίσεις cookies" + commentsDisabled = "Τα σχόλια είναι απενεργοποιημένα μέχρι να αποδεχτείτε τα λειτουργικά cookies." + + [cookies.necessary] + title = "Απαραίτητα" + text = "Αυτά τα cookies είναι απαραίτητα για τη λειτουργία του ιστότοπου και δεν μπορούν να απενεργοποιηθούν." + + [cookies.analytics] + title = "Αναλυτικά" + text = "Αυτά τα cookies μας βοηθούν να κατανοήσουμε πώς οι επισκέπτες αλληλεπιδρούν με τον ιστότοπό μας." + + [cookies.functional] + title = "Λειτουργικά" + text = "Αυτά τα cookies ενεργοποιούν λειτουργίες όπως σχόλια και ενσωματωμένο περιεχόμενο." diff --git a/i18n/en.toml b/i18n/en.toml index f1affad..5b0f118 100644 --- a/i18n/en.toml +++ b/i18n/en.toml @@ -52,3 +52,27 @@ darkMode = "Dark Mode" [footer] builtWith = "Built with {{ .Generator }}" designedBy = "Theme {{ .Theme }} designed by {{ .DesignedBy }}" + +[cookies] + title = "Cookie Consent" + text = "We use cookies to enhance your browsing experience and analyze site traffic." + acceptAll = "Accept All" + deny = "Deny" + managePreferences = "Manage preferences" + settingsTitle = "Cookie Preferences" + savePreferences = "Save preferences" + cancel = "Cancel" + footerLink = "Cookie settings" + commentsDisabled = "Comments are disabled until you accept functional cookies." + + [cookies.necessary] + title = "Necessary" + text = "These cookies are required for the website to function and cannot be disabled." + + [cookies.analytics] + title = "Analytics" + text = "These cookies help us understand how visitors interact with our website." + + [cookies.functional] + title = "Functional" + text = "These cookies enable features like comments and embedded content." diff --git a/i18n/es.toml b/i18n/es.toml index 09f2227..66c981d 100644 --- a/i18n/es.toml +++ b/i18n/es.toml @@ -52,3 +52,27 @@ darkMode = "Modo oscuro" [footer] builtWith = "Creado con {{ .Generator }}" designedBy = "Tema {{ .Theme }} diseñado por {{ .DesignedBy }}" + +[cookies] + title = "Consentimiento de cookies" + text = "Utilizamos cookies para mejorar su experiencia de navegación y analizar el tráfico del sitio." + acceptAll = "Aceptar todo" + deny = "Rechazar" + managePreferences = "Gestionar preferencias" + settingsTitle = "Preferencias de cookies" + savePreferences = "Guardar preferencias" + cancel = "Cancelar" + footerLink = "Configuración de cookies" + commentsDisabled = "Los comentarios están desactivados hasta que acepte las cookies funcionales." + + [cookies.necessary] + title = "Necesarias" + text = "Estas cookies son necesarias para el funcionamiento del sitio web y no se pueden desactivar." + + [cookies.analytics] + title = "Analíticas" + text = "Estas cookies nos ayudan a entender cómo los visitantes interactúan con nuestro sitio web." + + [cookies.functional] + title = "Funcionales" + text = "Estas cookies permiten funciones como comentarios y contenido incrustado." diff --git a/i18n/fa.toml b/i18n/fa.toml index 694a0ff..dbc81e0 100644 --- a/i18n/fa.toml +++ b/i18n/fa.toml @@ -52,3 +52,27 @@ darkMode = "حالت شب" [footer] builtWith = "قدرت گرفته از {{ .Generator }}" designedBy = "قالب {{ .Theme }} ساخته شده توسط {{ .DesignedBy }}" + +[cookies] + title = "رضایت کوکی" + text = "ما از کوکی‌ها برای بهبود تجربه مرورگری شما و تجزیه و تحلیل ترافیک سایت استفاده می‌کنیم." + acceptAll = "پذیرش همه" + deny = "رد کردن" + managePreferences = "مدیریت تنظیمات" + settingsTitle = "تنظیمات کوکی" + savePreferences = "ذخیره تنظیمات" + cancel = "لغو" + footerLink = "تنظیمات کوکی" + commentsDisabled = "نظرات تا زمانی که کوکی‌های کاربردی را بپذیرید غیرفعال هستند." + + [cookies.necessary] + title = "ضروری" + text = "این کوکی‌ها برای عملکرد وب‌سایت الزامی هستند و نمی‌توان آنها را غیرفعال کرد." + + [cookies.analytics] + title = "تجزیه و تحلیل" + text = "این کوکی‌ها به ما کمک می‌کنند تا بفهمیم بازدیدکنندگان چگونه با وب‌سایت ما تعامل دارند." + + [cookies.functional] + title = "کاربردی" + text = "این کوکی‌ها ویژگی‌هایی مانند نظرات و محتوای جاسازی‌شده را فعال می‌کنند." diff --git a/i18n/fr.toml b/i18n/fr.toml index 2a421d7..d7ee5bd 100644 --- a/i18n/fr.toml +++ b/i18n/fr.toml @@ -52,3 +52,27 @@ darkMode = "Mode sombre" [footer] builtWith = "Généré avec {{ .Generator }}" designedBy = "Thème {{ .Theme }} conçu par {{ .DesignedBy }}" + +[cookies] + title = "Consentement aux cookies" + text = "Nous utilisons des cookies pour améliorer votre expérience de navigation et analyser le trafic du site." + acceptAll = "Tout accepter" + deny = "Refuser" + managePreferences = "Gérer les préférences" + settingsTitle = "Préférences de cookies" + savePreferences = "Enregistrer les préférences" + cancel = "Annuler" + footerLink = "Paramètres des cookies" + commentsDisabled = "Les commentaires sont désactivés jusqu'à ce que vous acceptiez les cookies fonctionnels." + + [cookies.necessary] + title = "Nécessaires" + text = "Ces cookies sont nécessaires au fonctionnement du site et ne peuvent pas être désactivés." + + [cookies.analytics] + title = "Analytiques" + text = "Ces cookies nous aident à comprendre comment les visiteurs interagissent avec notre site." + + [cookies.functional] + title = "Fonctionnels" + text = "Ces cookies permettent des fonctionnalités comme les commentaires et le contenu intégré." diff --git a/i18n/hi.toml b/i18n/hi.toml index 57ead7a..ce97587 100644 --- a/i18n/hi.toml +++ b/i18n/hi.toml @@ -52,3 +52,27 @@ darkMode = "डार्क मोड" [footer] builtWith = "निर्मित {{ .Generator }} के साथ" designedBy = "थीम {{ .Theme }} द्वारा डिज़ाइन किया गया {{ .DesignedBy }}" + +[cookies] + title = "कुकी सहमति" + text = "हम आपके ब्राउज़िंग अनुभव को बेहतर बनाने और साइट ट्रैफ़िक का विश्लेषण करने के लिए कुकीज़ का उपयोग करते हैं।" + acceptAll = "सभी स्वीकार करें" + deny = "अस्वीकार करें" + managePreferences = "वरीयताएँ प्रबंधित करें" + settingsTitle = "कुकी वरीयताएँ" + savePreferences = "वरीयताएँ सहेजें" + cancel = "रद्द करें" + footerLink = "कुकी सेटिंग्स" + commentsDisabled = "जब तक आप कार्यात्मक कुकीज़ स्वीकार नहीं करते हैं, टिप्पणियाँ अक्षम हैं।" + + [cookies.necessary] + title = "आवश्यक" + text = "ये कुकीज़ वेबसाइट के कार्य के लिए आवश्यक हैं और इन्हें अक्षम नहीं किया जा सकता।" + + [cookies.analytics] + title = "विश्लेषण" + text = "ये कुकीज़ हमें यह समझने में मदद करती हैं कि विज़िटर हमारी वेबसाइट के साथ कैसे इंटरैक्ट करते हैं।" + + [cookies.functional] + title = "कार्यात्मक" + text = "ये कुकीज़ टिप्पणियों और एम्बेडेड सामग्री जैसी सुविधाओं को सक्षम करती हैं." diff --git a/i18n/hu.toml b/i18n/hu.toml index e8554d3..7250122 100644 --- a/i18n/hu.toml +++ b/i18n/hu.toml @@ -52,3 +52,27 @@ darkMode = "Sötét Mód" [footer] builtWith = "{{ .Generator }} használatával készült" designedBy = "A {{ .Theme }} dizájnt {{ .DesignedBy }} tervezte" + +[cookies] + title = "Süti hozzájárulás" + text = "Sütiket használunk a böngészési élmény javítása és a webhely forgalmának elemzése érdekében." + acceptAll = "Összes elfogadása" + deny = "Elutasítás" + managePreferences = "Beállítások kezelése" + settingsTitle = "Süti beállítások" + savePreferences = "Beállítások mentése" + cancel = "Mégse" + footerLink = "Süti beállítások" + commentsDisabled = "A hozzászólások le vannak tiltva, amíg nem fogadja el a funkcionális sütiket." + + [cookies.necessary] + title = "Szükséges" + text = "Ezek a sütik szükségesek a webhely működéséhez és nem lehet őket letiltani." + + [cookies.analytics] + title = "Analitikai" + text = "Ezek a sütik segítenek megérteni, hogyan lépnek kapcsolatba a látogatók a weboldalunkkal." + + [cookies.functional] + title = "Funkcionális" + text = "Ezek a sütik olyan funkciókat tesznek lehetővé, mint a hozzászólások és a beágyazott tartalom." diff --git a/i18n/id.toml b/i18n/id.toml index 96b92b2..e40ea3d 100644 --- a/i18n/id.toml +++ b/i18n/id.toml @@ -52,3 +52,27 @@ darkMode = "Mode Gelap" [footer] builtWith = "Dibangun dengan {{ .Generator }}" designedBy = "Tema {{ .Theme }} dirancang oleh {{ .DesignedBy }}" + +[cookies] + title = "Persetujuan Cookie" + text = "Kami menggunakan cookie untuk meningkatkan pengalaman browsing Anda dan menganalisis lalu lintas situs." + acceptAll = "Terima Semua" + deny = "Tolak" + managePreferences = "Kelola preferensi" + settingsTitle = "Preferensi Cookie" + savePreferences = "Simpan preferensi" + cancel = "Batal" + footerLink = "Pengaturan cookie" + commentsDisabled = "Komentar dinonaktifkan sampai Anda menerima cookie fungsional." + + [cookies.necessary] + title = "Diperlukan" + text = "Cookie ini diperlukan agar situs web berfungsi dan tidak dapat dinonaktifkan." + + [cookies.analytics] + title = "Analitik" + text = "Cookie ini membantu kami memahami bagaimana pengunjung berinteraksi dengan situs web kami." + + [cookies.functional] + title = "Fungsional" + text = "Cookie ini mengaktifkan fitur seperti komentar dan konten yang disematkan." diff --git a/i18n/it.toml b/i18n/it.toml index f95191c..7b4bcdc 100644 --- a/i18n/it.toml +++ b/i18n/it.toml @@ -52,3 +52,27 @@ darkMode = "Modalità scura" [footer] builtWith = "Realizzato con {{ .Generator }}" designedBy = "Tema {{ .Theme }} realizzato da {{ .DesignedBy }}" + +[cookies] + title = "Consenso ai cookie" + text = "Utilizziamo i cookie per migliorare la tua esperienza di navigazione e analizzare il traffico del sito." + acceptAll = "Accetta tutti" + deny = "Rifiuta" + managePreferences = "Gestisci preferenze" + settingsTitle = "Preferenze cookie" + savePreferences = "Salva preferenze" + cancel = "Annulla" + footerLink = "Impostazioni cookie" + commentsDisabled = "I commenti sono disabilitati finché non accetti i cookie funzionali." + + [cookies.necessary] + title = "Necessari" + text = "Questi cookie sono necessari per il funzionamento del sito web e non possono essere disattivati." + + [cookies.analytics] + title = "Analitici" + text = "Questi cookie ci aiutano a capire come i visitatori interagiscono con il nostro sito web." + + [cookies.functional] + title = "Funzionali" + text = "Questi cookie abilitano funzionalità come commenti e contenuti incorporati." diff --git a/i18n/ja.toml b/i18n/ja.toml index 81b1130..64a14cd 100644 --- a/i18n/ja.toml +++ b/i18n/ja.toml @@ -43,3 +43,27 @@ darkMode = "ダークモード" [footer] builtWith = "{{ .Generator }} で構築されています。" designedBy = "テーマ {{ .Theme }} は {{ .DesignedBy }} によって設計されています。" + +[cookies] + title = "Cookieの同意" + text = "ブラウジング体験を向上させ、サイトトラフィックを分析するためにCookieを使用しています。" + acceptAll = "すべて受け入れる" + deny = "拒否" + managePreferences = "設定を管理" + settingsTitle = "Cookie設定" + savePreferences = "設定を保存" + cancel = "キャンセル" + footerLink = "Cookie設定" + commentsDisabled = "機能的なCookieを受け入れるまで、コメントは無効になっています。" + + [cookies.necessary] + title = "必須" + text = "これらのCookieはウェブサイトの機能に必要であり、無効にすることはできません。" + + [cookies.analytics] + title = "分析" + text = "これらのCookieは、訪問者が当サイトとどのように対話するかを理解するのに役立ちます。" + + [cookies.functional] + title = "機能的" + text = "これらのCookieは、コメントや埋め込みコンテンツなどの機能を有効にします." diff --git a/i18n/ko.toml b/i18n/ko.toml index 6bbcb63..d72ca0d 100644 --- a/i18n/ko.toml +++ b/i18n/ko.toml @@ -52,3 +52,27 @@ darkMode = "다크 모드" [footer] builtWith = "{{ .Generator }}로 만듦" designedBy = "{{ .DesignedBy }}의 {{ .Theme }} 테마 사용 중" + +[cookies] + title = "쿠키 동의" + text = "브라우징 경험을 향상시키고 사이트 트래픽을 분석하기 위해 쿠키를 사용합니다." + acceptAll = "모두 허용" + deny = "거부" + managePreferences = "설정 관리" + settingsTitle = "쿠키 설정" + savePreferences = "설정 저장" + cancel = "취소" + footerLink = "쿠키 설정" + commentsDisabled = "기능적 쿠키를 수락할 때까지 댓글이 비활성화됩니다." + + [cookies.necessary] + title = "필수" + text = "이 쿠키는 웹사이트 기능에 필요하며 비활성화할 수 없습니다." + + [cookies.analytics] + title = "분석" + text = "이 쿠키는 방문자가 웹사이트와 상호작용하는 방식을 이해하는 데 도움이 됩니다." + + [cookies.functional] + title = "기능적" + text = "이 쿠키는 댓글 및 임베디드 콘텐츠와 같은 기능을 활성화합니다." diff --git a/i18n/nl.toml b/i18n/nl.toml index 405c7fe..579bd39 100644 --- a/i18n/nl.toml +++ b/i18n/nl.toml @@ -47,3 +47,27 @@ darkMode = "Donkere modus" [footer] builtWith = "Gemaakt met {{ .Generator }}" designedBy = "Theme {{ .Theme }} ontworpen door {{ .DesignedBy }}" + +[cookies] + title = "Cookie-toestemming" + text = "We gebruiken cookies om uw browse-ervaring te verbeteren en siteverkeer te analyseren." + acceptAll = "Accepteer alles" + deny = "Weigeren" + managePreferences = "Voorkeuren beheren" + settingsTitle = "Cookie-voorkeuren" + savePreferences = "Voorkeuren opslaan" + cancel = "Annuleren" + footerLink = "Cookie-instellingen" + commentsDisabled = "Reacties zijn uitgeschakeld totdat u functionele cookies accepteert." + + [cookies.necessary] + title = "Noodzakelijk" + text = "Deze cookies zijn vereist voor de werking van de website en kunnen niet worden uitgeschakeld." + + [cookies.analytics] + title = "Analyse" + text = "Deze cookies helpen ons begrijpen hoe bezoekers omgaan met onze website." + + [cookies.functional] + title = "Functioneel" + text = "Deze cookies maken functies mogelijk zoals reacties en ingesloten inhoud." diff --git a/i18n/oc.toml b/i18n/oc.toml index f7d5d03..ff62182 100644 --- a/i18n/oc.toml +++ b/i18n/oc.toml @@ -52,3 +52,27 @@ darkMode = "Mòde fosc" [footer] builtWith = "Creat amb {{ .Generator }}" designedBy = "Tàma {{ .Theme }} concebut per {{ .DesignedBy }}" + +[cookies] + title = "Consentiment de cookies" + text = "Utilizem cookies per melhorar vòstra experiéncia de navegacion e analisar lo trafic del site." + acceptAll = "Acceptar tot" + deny = "Refusar" + managePreferences = "Gerir las preferéncias" + settingsTitle = "Preferéncias de cookies" + savePreferences = "Enregistrar las preferéncias" + cancel = "Anullar" + footerLink = "Paramètres de cookies" + commentsDisabled = "Los comentaris son desactivats fins qu'acceptatz las cookies foncionalas." + + [cookies.necessary] + title = "Necessaris" + text = "Aquestes cookies son necessàrias pel foncionament del site web e se pòdon pas desactivar." + + [cookies.analytics] + title = "Analiticas" + text = "Aquestes cookies nos ajudan a comprendre cossí los visitaires interagisson amb nòstre site web." + + [cookies.functional] + title = "Foncionalas" + text = "Aquestes cookies activan de foncionalitats coma los comentaris e lo contengut incorporat." diff --git a/i18n/pl.toml b/i18n/pl.toml index b2f8667..9ed88e2 100644 --- a/i18n/pl.toml +++ b/i18n/pl.toml @@ -63,3 +63,27 @@ darkMode = "Tryb ciemny" [footer] builtWith = "Zbudowano z {{ .Generator }}" designedBy = "Motyw {{ .Theme }} zaprojektowany przez {{ .DesignedBy }}" + +[cookies] + title = "Zgoda na pliki cookie" + text = "Używamy plików cookie, aby poprawić Twoje wrażenia z przeglądania i analizować ruch w witrynie." + acceptAll = "Akceptuj wszystkie" + deny = "Odrzuć" + managePreferences = "Zarządzaj preferencjami" + settingsTitle = "Preferencje plików cookie" + savePreferences = "Zapisz preferencje" + cancel = "Anuluj" + footerLink = "Ustawienia plików cookie" + commentsDisabled = "Komentarze są wyłączone, dopóki nie zaakceptujesz funkcjonalnych plików cookie." + + [cookies.necessary] + title = "Niezbędne" + text = "Te pliki cookie są wymagane do działania witryny i nie można ich wyłączyć." + + [cookies.analytics] + title = "Analityczne" + text = "Te pliki cookie pomagają nam zrozumieć, jak odwiedzający wchodzą w interakcję z naszą witryną." + + [cookies.functional] + title = "Funkcjonalne" + text = "Te pliki cookie włączają funkcje takie jak komentarze i osadzone treści." diff --git a/i18n/pt-br.toml b/i18n/pt-br.toml index dc25b58..20d1eab 100644 --- a/i18n/pt-br.toml +++ b/i18n/pt-br.toml @@ -52,3 +52,27 @@ darkMode = "Modo Escuro" [footer] builtWith = "Criado com {{ .Generator }}" designedBy = "Tema {{ .Theme }} desenvolvido por {{ .DesignedBy }}" + +[cookies] + title = "Consentimento de cookies" + text = "Usamos cookies para melhorar sua experiência de navegação e analisar o tráfego do site." + acceptAll = "Aceitar todos" + deny = "Recusar" + managePreferences = "Gerenciar preferências" + settingsTitle = "Preferências de cookies" + savePreferences = "Salvar preferências" + cancel = "Cancelar" + footerLink = "Configurações de cookies" + commentsDisabled = "Os comentários estão desativados até que você aceite os cookies funcionais." + + [cookies.necessary] + title = "Necessários" + text = "Estes cookies são necessários para o funcionamento do site e não podem ser desativados." + + [cookies.analytics] + title = "Analíticos" + text = "Estes cookies nos ajudam a entender como os visitantes interagem com nosso site." + + [cookies.functional] + title = "Funcionais" + text = "Estes cookies habilitam recursos como comentários e conteúdo incorporado." diff --git a/i18n/pt-pt.toml b/i18n/pt-pt.toml index 74c9d19..d36a01f 100644 --- a/i18n/pt-pt.toml +++ b/i18n/pt-pt.toml @@ -52,3 +52,27 @@ darkMode = "Modo Escuro" [footer] builtWith = "Criado com {{ .Generator }}" designedBy = "Tema {{ .Theme }} desenvolvido por {{ .DesignedBy }}" + +[cookies] + title = "Consentimento de cookies" + text = "Utilizamos cookies para melhorar a sua experiência de navegação e analisar o tráfego do site." + acceptAll = "Aceitar todos" + deny = "Recusar" + managePreferences = "Gerir preferências" + settingsTitle = "Preferências de cookies" + savePreferences = "Guardar preferências" + cancel = "Cancelar" + footerLink = "Definições de cookies" + commentsDisabled = "Os comentários estão desativados até que aceite os cookies funcionais." + + [cookies.necessary] + title = "Necessários" + text = "Estes cookies são necessários para o funcionamento do website e não podem ser desativados." + + [cookies.analytics] + title = "Analíticos" + text = "Estes cookies ajudam-nos a compreender como os visitantes interagem com o nosso website." + + [cookies.functional] + title = "Funcionais" + text = "Estes cookies permitem funcionalidades como comentários e conteúdo incorporado." diff --git a/i18n/ru.toml b/i18n/ru.toml index 2ab0340..e6f26d0 100644 --- a/i18n/ru.toml +++ b/i18n/ru.toml @@ -53,3 +53,27 @@ darkMode = "Тёмный режим" [footer] builtWith = "Создано при помощи {{ .Generator }}" designedBy = "Тема {{ .Theme }}, дизайн {{ .DesignedBy }}" + +[cookies] + title = "Согласие на использование файлов cookie" + text = "Мы используем файлы cookie для улучшения вашего опыта просмотра и анализа трафика сайта." + acceptAll = "Принять все" + deny = "Отклонить" + managePreferences = "Управление настройками" + settingsTitle = "Настройки файлов cookie" + savePreferences = "Сохранить настройки" + cancel = "Отмена" + footerLink = "Настройки файлов cookie" + commentsDisabled = "Комментарии отключены, пока вы не примете функциональные файлы cookie." + + [cookies.necessary] + title = "Необходимые" + text = "Эти файлы cookie необходимы для работы сайта и не могут быть отключены." + + [cookies.analytics] + title = "Аналитика" + text = "Эти файлы cookie помогают нам понять, как посетители взаимодействуют с нашим сайтом." + + [cookies.functional] + title = "Функциональные" + text = "Эти файлы cookie включают такие функции, как комментарии и встроенный контент." diff --git a/i18n/sk.toml b/i18n/sk.toml index d2225fa..6942065 100644 --- a/i18n/sk.toml +++ b/i18n/sk.toml @@ -52,3 +52,27 @@ darkMode = "Tmavý režim" [footer] builtWith = "Vytvorené pomocou {{ .Generator }}" designedBy = "Šablóna {{ .Theme }} od {{ .DesignedBy }}" + +[cookies] + title = "Súhlas s cookies" + text = "Používame cookies na zlepšenie vášho prehliadania a analýzu návštevnosti webu." + acceptAll = "Prijať všetko" + deny = "Odmietnuť" + managePreferences = "Spravovať predvoľby" + settingsTitle = "Predvoľby cookies" + savePreferences = "Uložiť predvoľby" + cancel = "Zrušiť" + footerLink = "Nastavenia cookies" + commentsDisabled = "Komentáre sú zakázané, kým neprijmete funkčné cookies." + + [cookies.necessary] + title = "Nutné" + text = "Tieto cookies sú nutné pre fungovanie webu a nemožno ich zakázať." + + [cookies.analytics] + title = "Analytické" + text = "Tieto cookies nám pomáhajú pochopiť, ako návštevníci interagujú s naším webom." + + [cookies.functional] + title = "Funkčné" + text = "Tieto cookies umožňujú funkcie ako komentáre a vložený obsah." diff --git a/i18n/th.toml b/i18n/th.toml index 7b828a7..7c80501 100644 --- a/i18n/th.toml +++ b/i18n/th.toml @@ -49,3 +49,27 @@ darkMode = "ธีมมืด" [footer] builtWith = "ถูกสร้างด้วย {{ .Generator }}" designedBy = "ธีม {{ .Theme }} ออกแบบโดย {{ .DesignedBy }}" + +[cookies] + title = "ความยินยอมคุกกี้" + text = "เราใช้คุกกี้เพื่อปรับปรุงประสบการณ์การเรียกดูของคุณและวิเคราะห์การเข้าชมเว็บไซต์" + acceptAll = "ยอมรับทั้งหมด" + deny = "ปฏิเสธ" + managePreferences = "จัดการการตั้งค่า" + settingsTitle = "การตั้งค่าคุกกี้" + savePreferences = "บันทึกการตั้งค่า" + cancel = "ยกเลิก" + footerLink = "การตั้งค่าคุกกี้" + commentsDisabled = "ความคิดเห็นถูกปิดการใช้งานจนกว่าคุณจะยอมรับคุกกี้เชิงหน้าที่" + + [cookies.necessary] + title = "จำเป็น" + text = "คุกกี้เหล่านี้จำเป็นสำหรับการทำงานของเว็บไซต์และไม่สามารถปิดการใช้งานได้" + + [cookies.analytics] + title = "การวิเคราะห์" + text = "คุกกี้เหล่านี้ช่วยให้เราเข้าใจว่าผู้เยี่ยมชมโต้ตอบกับเว็บไซต์ของเราอย่างไร" + + [cookies.functional] + title = "เชิงหน้าที่" + text = "คุกกี้เหล่านี้เปิดใช้งานคุณสมบัติต่างๆ เช่น ความคิดเห็นและเนื้อหาที่ฝังไว้" diff --git a/i18n/tr.toml b/i18n/tr.toml index 7997a72..8edaa84 100644 --- a/i18n/tr.toml +++ b/i18n/tr.toml @@ -52,3 +52,27 @@ darkMode = "Koyu Mod" [footer] builtWith = "{{ .Generator }} ile oluşturuldu." designedBy = "{{ .Theme }} teması {{ .DesignedBy }} tarafından tasarlandı" + +[cookies] + title = "Çerez Onayı" + text = "Tarayıcı deneyiminizi iyileştirmek ve site trafiğini analiz etmek için çerezler kullanıyoruz." + acceptAll = "Tümünü Kabul Et" + deny = "Reddet" + managePreferences = "Tercihleri yönet" + settingsTitle = "Çerez Tercihleri" + savePreferences = "Tercihleri kaydet" + cancel = "İptal" + footerLink = "Çerez ayarları" + commentsDisabled = "İşlevsel çerezleri kabul edene kadar yorumlar devre dışıdır." + + [cookies.necessary] + title = "Gerekli" + text = "Bu çerezler web sitesinin çalışması için gereklidir ve devre dışı bırakılamaz." + + [cookies.analytics] + title = "Analitik" + text = "Bu çerezler, ziyaretçilerin web sitemizle nasıl etkileşimde bulunduğunu anlamamıza yardımcı olur." + + [cookies.functional] + title = "İşlevsel" + text = "Bu çerezler, yorumlar ve gömülü içerik gibi özellikleri etkinleştirir." diff --git a/i18n/uk.toml b/i18n/uk.toml index fd62c79..32e20ad 100644 --- a/i18n/uk.toml +++ b/i18n/uk.toml @@ -53,3 +53,27 @@ darkMode = "Темна тема" [footer] builtWith = "Створено з {{ .Generator }}" designedBy = "Тема {{ .Theme }}, дизайн {{ .DesignedBy }}" + +[cookies] + title = "Згода на використання файлів cookie" + text = "Ми використовуємо файли cookie для покращення вашого досвіду перегляду та аналізу трафіку сайту." + acceptAll = "Прийняти все" + deny = "Відхилити" + managePreferences = "Керувати налаштуваннями" + settingsTitle = "Налаштування файлів cookie" + savePreferences = "Зберегти налаштування" + cancel = "Скасувати" + footerLink = "Налаштування файлів cookie" + commentsDisabled = "Коментарі вимкнено, доки ви не приймете функціональні файли cookie." + + [cookies.necessary] + title = "Необхідні" + text = "Ці файли cookie необхідні для роботи сайту і не можуть бути вимкнені." + + [cookies.analytics] + title = "Аналітика" + text = "Ці файли cookie допомагають нам зрозуміти, як відвідувачі взаємодіють з нашим сайтом." + + [cookies.functional] + title = "Функціональні" + text = "Ці файли cookie вмикають такі функції, як коментарі та вбудований контент." diff --git a/i18n/vi.toml b/i18n/vi.toml index 16824b5..90a4726 100644 --- a/i18n/vi.toml +++ b/i18n/vi.toml @@ -52,3 +52,27 @@ darkMode = "Chế độ nền tối" [footer] builtWith = "Built with {{ .Generator }}" designedBy = "Theme {{ .Theme }} thiết kế bởi {{ .DesignedBy }}" + +[cookies] + title = "Đồng ý cookie" + text = "Chúng tôi sử dụng cookie để nâng cao trải nghiệm duyệt web của bạn và phân tích lưu lượng truy cập trang web." + acceptAll = "Chấp nhận tất cả" + deny = "Từ chối" + managePreferences = "Quản lý tùy chọn" + settingsTitle = "Tùy chọn cookie" + savePreferences = "Lưu tùy chọn" + cancel = "Hủy" + footerLink = "Cài đặt cookie" + commentsDisabled = "Bình luận bị vô hiệu hóa cho đến khi bạn chấp nhận cookie chức năng." + + [cookies.necessary] + title = "Cần thiết" + text = "Những cookie này là cần thiết để trang web hoạt động và không thể vô hiệu hóa." + + [cookies.analytics] + title = "Phân tích" + text = "Những cookie này giúp chúng tôi hiểu cách khách truy cập tương tác với trang web của chúng tôi." + + [cookies.functional] + title = "Chức năng" + text = "Những cookie này cho phép các tính năng như bình luận và nội dung nhúng." diff --git a/i18n/zh-hant-hk.toml b/i18n/zh-hant-hk.toml index 9b8d5bb..f68d205 100644 --- a/i18n/zh-hant-hk.toml +++ b/i18n/zh-hant-hk.toml @@ -43,3 +43,27 @@ darkMode = "深色模式" [footer] builtWith = "使用 {{ .Generator }} 建立" designedBy = "主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計" + +[cookies] + title = "Cookie 同意" + text = "我們使用 Cookie 來增強您的瀏覽體驗並分析網站流量。" + acceptAll = "接受全部" + deny = "拒絕" + managePreferences = "管理偏好設定" + settingsTitle = "Cookie 偏好設定" + savePreferences = "儲存偏好設定" + cancel = "取消" + footerLink = "Cookie 設定" + commentsDisabled = "評論已停用,直到您接受功能性 Cookie。" + + [cookies.necessary] + title = "必要" + text = "這些 Cookie 是網站運作所必需的,無法停用。" + + [cookies.analytics] + title = "分析" + text = "這些 Cookie 幫助我們了解訪客如何與我們的網站互動。" + + [cookies.functional] + title = "功能性" + text = "這些 Cookie 啟用評論和嵌入內容等功能." diff --git a/i18n/zh-hant-tw.toml b/i18n/zh-hant-tw.toml index 84e5ffd..4284c2f 100644 --- a/i18n/zh-hant-tw.toml +++ b/i18n/zh-hant-tw.toml @@ -43,3 +43,27 @@ darkMode = "夜晚模式" [footer] builtWith = "使用 {{ .Generator }} 建立" designedBy = "主題 {{ .Theme }} 由 {{ .DesignedBy }} 設計" + +[cookies] + title = "Cookie 同意" + text = "我們使用 Cookie 來增強您的瀏覽體驗並分析網站流量。" + acceptAll = "接受全部" + deny = "拒絕" + managePreferences = "管理偏好設定" + settingsTitle = "Cookie 偏好設定" + savePreferences = "儲存偏好設定" + cancel = "取消" + footerLink = "Cookie 設定" + commentsDisabled = "評論已停用,直到您接受功能性 Cookie。" + + [cookies.necessary] + title = "必要" + text = "這些 Cookie 是網站運作所必需的,無法停用。" + + [cookies.analytics] + title = "分析" + text = "這些 Cookie 幫助我們了解訪客如何與我們的網站互動。" + + [cookies.functional] + title = "功能性" + text = "這些 Cookie 啟用評論和嵌入內容等功能." diff --git a/i18n/zh.toml b/i18n/zh.toml index 2c62ecc..6a539a5 100644 --- a/i18n/zh.toml +++ b/i18n/zh.toml @@ -43,3 +43,27 @@ darkMode = "暗色模式" [footer] builtWith = "使用 {{ .Generator }} 构建" designedBy = "主题 {{ .Theme }} 由 {{ .DesignedBy }} 设计" + +[cookies] + title = "Cookie 同意" + text = "我们使用 Cookie 来增强您的浏览体验并分析网站流量。" + acceptAll = "接受所有" + deny = "拒绝" + managePreferences = "管理偏好设置" + settingsTitle = "Cookie 偏好设置" + savePreferences = "保存偏好设置" + cancel = "取消" + footerLink = "Cookie 设置" + commentsDisabled = "评论已禁用,直到您接受功能性 Cookie。" + + [cookies.necessary] + title = "必要" + text = "这些 Cookie 是网站运行所必需的,无法禁用。" + + [cookies.analytics] + title = "分析" + text = "这些 Cookie 帮助我们了解访问者如何与我们的网站互动。" + + [cookies.functional] + title = "功能性" + text = "这些 Cookie 启用评论和嵌入内容等功能." diff --git a/layouts/_partials/comments/include.html b/layouts/_partials/comments/include.html index a3d0618..6fc6cd3 100644 --- a/layouts/_partials/comments/include.html +++ b/layouts/_partials/comments/include.html @@ -1,3 +1,47 @@ {{ if .Site.Params.comments.enabled }} - {{ partial (printf "comments/provider/%s" .Site.Params.comments.provider) . }} + {{- $needsConsent := and .Site.Params.cookies.enabled .Site.Params.cookies.categories.functional -}} + {{- if $needsConsent -}} + {{/* Consent-gated comments - show placeholder until functional consent */}} + + + + {{- else -}} + {{/* No consent required - load comments normally */}} + {{ partial (printf "comments/provider/%s" .Site.Params.comments.provider) . }} + {{- end -}} {{ end }} \ No newline at end of file diff --git a/layouts/_partials/cookies/analytics.html b/layouts/_partials/cookies/analytics.html new file mode 100644 index 0000000..c4e19ef --- /dev/null +++ b/layouts/_partials/cookies/analytics.html @@ -0,0 +1,50 @@ +{{- if not site.Config.Privacy.GoogleAnalytics.Disable -}} + {{- with site.Config.Services.GoogleAnalytics.ID -}} + {{- if strings.HasPrefix (lower .) "ua-" -}} + {{- warnf "Google Analytics 4 (GA4) replaced Google Universal Analytics (UA) effective 1 July 2023. See https://support.google.com/analytics/answer/11583528. Create a GA4 property and data stream, then replace the Google Analytics ID in your site configuration with the new value." -}} + {{- else -}} + {{/* Consent-gated Google Analytics - only loads after analytics consent */}} + + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/layouts/_partials/cookies/banner.html b/layouts/_partials/cookies/banner.html new file mode 100644 index 0000000..a5f7174 --- /dev/null +++ b/layouts/_partials/cookies/banner.html @@ -0,0 +1,68 @@ +{{- $cfg := .Site.Params.cookies -}} +{{- $categories := $cfg.categories -}} + + diff --git a/layouts/_partials/cookies/include.html b/layouts/_partials/cookies/include.html new file mode 100644 index 0000000..ff6c6bd --- /dev/null +++ b/layouts/_partials/cookies/include.html @@ -0,0 +1,9 @@ +{{- if .Site.Params.cookies.enabled -}} + {{/* Render the banner HTML */}} + {{ partial "cookies/banner.html" . }} + + {{/* Load the consent manager script */}} + {{- $opts := dict "minify" hugo.IsProduction -}} + {{- $script := resources.Get "ts/cookies.ts" | js.Build $opts | fingerprint -}} + +{{- end -}} diff --git a/layouts/_partials/footer/include.html b/layouts/_partials/footer/include.html index b4c0b99..54d85a8 100644 --- a/layouts/_partials/footer/include.html +++ b/layouts/_partials/footer/include.html @@ -1,2 +1,3 @@ +{{ partial "cookies/include.html" . }} {{ partialCached "footer/components/script.html" . }} -{{ partial "footer/custom.html" . }} \ No newline at end of file +{{ partial "footer/custom.html" . }} diff --git a/layouts/_partials/head/head.html b/layouts/_partials/head/head.html index 16b2891..53cc317 100644 --- a/layouts/_partials/head/head.html +++ b/layouts/_partials/head/head.html @@ -28,5 +28,10 @@ {{ end }} -{{- partial "google_analytics.html" . -}} +{{- if .Site.Params.cookies.enabled -}} + {{- partial "cookies/analytics.html" . -}} +{{- else -}} + {{- template "_internal/google_analytics.html" . -}} +{{- end -}} + {{- partial "head/custom.html" . -}}