From 69e0fcf95f073873200ad182c77b7a6850f680a9 Mon Sep 17 00:00:00 2001 From: David Arcos Date: Thu, 8 Oct 2026 09:33:31 +0200 Subject: [PATCH 1/8] Hold who the association is in config, not in a page of legal prose Spanish law 34/2002, LSSI-CE article 10, requires a site run by an association to publish its name, its address, an email, its entry in the register it is recorded in, and its tax number. The legal notice page that shows them is written and waiting; two of the five facts are missing and no volunteer can supply them. They go in config.toml, under [params.association], rather than in the text of that page. Two reasons. The association can correct a fact without anyone editing a page of legal prose, which is the kind of edit that goes wrong. And the gap is visible: bin/check-content reports an empty one on every run, instead of the fact being absent from a paragraph nobody rereads. Filled already: the legal name, and the tax number G67254045. Empty, and only the Management Board can fill them: the registered address, and the entry in the Registre d'Associacions de la Generalitat de Catalunya. The check warns and does not fail. The site builds and serves without them, and an error would turn every pull request red for a reason no contributor could fix. The gate is the legal notice page, which cannot be published while they are empty: that page is the one place the law asks for these, and a page that leaves them out does not do the job it exists for. Checked both ways: with the two keys empty the run ends 0 errors and 13 warnings, and with them filled, 11. --- bin/check-content | 39 +++++++++++++++++++++++++++++++++++++++ config.toml | 18 ++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/bin/check-content b/bin/check-content index f6048491..aaf3758c 100755 --- a/bin/check-content +++ b/bin/check-content @@ -17,6 +17,7 @@ import pathlib import re import struct import sys +import tomllib import yaml @@ -345,6 +346,43 @@ SECURITY_TXT = ROOT / "static" / ".well-known" / "security.txt" SECURITY_TXT_NOTICE_DAYS = 30 +CONFIG = ROOT / "config.toml" + +# The keys of [params.association] that only the Management Board can fill, +# and what each one is for. See the comment in config.toml. +ASSOCIATION_KEYS = { + "address": "the registered address, which LSSI-CE article 10 requires the " + "legal notice to publish", + "registry": "the entry in the Registre d'Associacions de la Generalitat " + "de Catalunya, which LSSI-CE article 10 requires too", +} + + +def check_association(): + """The legal notice reads who the association is from config.toml. + + Two of those facts are not a volunteer's to write: the registered address + and the entry in the register of associations. They start empty, and this + says so on every run rather than letting the legal notice go out with a + gap in the one section the law asks for. + + A warning and not an error: the site builds and serves fine without them, + and an error would turn every pull request red for a reason no + contributor can fix. The page that needs them is the gate. + """ + try: + with open(CONFIG, "rb") as handle: + config = tomllib.load(handle) + except (OSError, tomllib.TOMLDecodeError) as problem: + error(CONFIG, f"cannot be read: {problem}") + return + association = (config.get("params") or {}).get("association") or {} + for key, what in sorted(ASSOCIATION_KEYS.items()): + if not str(association.get(key, "")).strip(): + warn(CONFIG, f"params.association.{key} is empty. It is {what}. " + f"Only the Management Board can fill it.") + + def check_security_txt(): """Report a security.txt that has expired, or is about to. @@ -387,6 +425,7 @@ def main(): check_agenda() check_orphans(people, listed_people) check_security_txt() + check_association() for line in warnings: print(f"WARNING {line}") diff --git a/config.toml b/config.toml index 4d2a197a..d962745f 100644 --- a/config.toml +++ b/config.toml @@ -33,6 +33,24 @@ unsafe=true short_name = "PyBCN" extended_name = "The Barcelona Python Association" + # Who the association is in law. Spanish law 34/2002 (LSSI-CE) article 10 + # requires a site run by an association to publish its name, its address, + # an email, its entry in the register it is recorded in, and its tax + # number. The legal notice page is what shows them, and reads them from + # here rather than holding them in its own text, so that the association + # can correct a fact without a volunteer editing a page of legal prose. + # + # address and registry are empty and only the Management Board can fill + # them. bin/check-content reports an empty one as a warning. The legal + # notice page cannot be published while they are empty: the page is the + # one place the law asks for them, and a page that leaves them out does + # not do the job it exists for. + [params.association] + legal_name = "Associació Python Barcelona" + tax_id = "G67254045" + address = "" + registry = "" + main_contact_name_pyladies = "PyLadiesBCN Organizers" main_contact_email_pyladies = "pyladies-bcn@googlegroups.com" From 15d11087888d143a5f7546acf6b032b72acee3c7 Mon Sep 17 00:00:00 2001 From: David Arcos Date: Wed, 7 Oct 2026 11:10:57 +0200 Subject: [PATCH 2/8] Add the legal notice page The site identifies the association nowhere, which the LSSI-CE (article 10) requires of any organisation that runs a website. This page gives the name, the CIF, the contact mailbox, the terms of use and the applicable law. The registered address and the registry number are not in the repository. The page shows them as pending: it must not be published until they are filled in. --- content/pybcn_association/legal-notice.md | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 content/pybcn_association/legal-notice.md diff --git a/content/pybcn_association/legal-notice.md b/content/pybcn_association/legal-notice.md new file mode 100644 index 00000000..f57f1e5e --- /dev/null +++ b/content/pybcn_association/legal-notice.md @@ -0,0 +1,61 @@ +--- +title: "Legal notice" +description: "Who runs pybcn.org, how to reach us, and the terms of use" +menu: + main: + parent: 'The association' +weight: 6 +aliases: +- /legal-notice + +layout: single +heroBackground: /images/photos/reg-desk-pyday-2019.jpg + +--- + +This website, [pybcn.org](https://pybcn.org), is run by **Associació Python Barcelona** (PyBCN), a non-profit association of volunteers who organise Python meetups and events in Barcelona. + +## Who we are + +- **Name**: Associació Python Barcelona +- **Tax ID (CIF)**: G67254045 +- **Registered address**: *pending. The association must add its registered address here before this page is published.* +- **Registry**: *pending. The registration number in the Registre d'Associacions de la Generalitat de Catalunya must be added here before this page is published.* +- **Email**: [pybcn@googlegroups.com](mailto:pybcn@googlegroups.com) + +The Management Board is responsible for this website. You can see who sits on it on the [Information](/pybcn_association/information/) page. + +## What this site is + +This is an informational site. It describes the association, its events, the people who organise them and speak at them, and how to join, propose a talk, or sponsor us. Nothing is sold through this site. The membership fee is paid on PayPal's own site, not here. Some pages embed a Google Form or a Google Calendar; those are served by Google. + +The site is a set of static pages, published from a public repository on GitHub and served by GitHub Pages. We keep no server of our own and we run no analytics. The [Privacy policy](/pybcn_association/privacy-policy/) says what personal data this involves. + +## Using the content + +- The text on this site is written by volunteers and belongs to the association. You can quote it with a link to the page. Ask us before you reuse more than that. +- The photographs and biographies on the people pages belong to the people shown. Do not reuse them without their permission. +- The logos of sponsors and partner organisations belong to their owners. +- The site code is in a [public repository](https://github.com/pybcn/pybcn.github.io) on GitHub. The theme is free software under the MIT licence. + +## Links to other sites + +We link to Meetup, YouTube, GitHub, LinkedIn, Google Docs, and to the sites of speakers and sponsors. We do not control those sites and we are not responsible for what they publish or how they treat your data. + +## Accuracy + +Volunteers maintain this site in their free time. We try to keep it correct and we fix errors when someone tells us. Event details can change after they are published: the Meetup event page is the one to trust for date, time, and venue. We cannot promise that the site is always available or free of errors. + +## Code of Conduct + +Our [Code of Conduct](/pybcn_association/coc/) applies to every space the association runs, online and in person. + +## Changes to this notice + +We may update this notice. Every change is visible in the [history of this page](https://github.com/pybcn/pybcn.github.io/commits/edition/content/pybcn_association/legal-notice.md) on GitHub. + +## Applicable law + +Spanish law applies to this notice and to the use of this site. Any dispute goes to the courts of Barcelona, unless the law gives you the right to the courts of your own domicile. + +Last updated: 2026-10-07 From c1333666ab8e31ecc5917c932044287598442262 Mon Sep 17 00:00:00 2001 From: David Arcos Date: Wed, 7 Oct 2026 11:11:35 +0200 Subject: [PATCH 3/8] Add the privacy policy page The site publishes 138 people pages with a name, a photograph, a biography and profile links, links Google Forms, embeds a Google Calendar, and sends members to PayPal, with no privacy policy. GDPR articles 13 and 14 require one. The page names the controller, lists each kind of data the site involves with its purpose and legal basis, names the third parties (Google, PayPal, GitHub), states that the site sets no cookies and runs no analytics, and gives one mailbox to exercise the rights of articles 15 to 22, including the removal of a people page. The registered address is not in the repository and shows as pending. --- content/pybcn_association/privacy-policy.md | 97 +++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 content/pybcn_association/privacy-policy.md diff --git a/content/pybcn_association/privacy-policy.md b/content/pybcn_association/privacy-policy.md new file mode 100644 index 00000000..ba013441 --- /dev/null +++ b/content/pybcn_association/privacy-policy.md @@ -0,0 +1,97 @@ +--- +title: "Privacy policy" +description: "What personal data this site involves, why, and how to ask us to change or remove it" +menu: + main: + parent: 'The association' +weight: 7 +aliases: +- /privacy-policy + +layout: single +heroBackground: /images/photos/people-pyday-2019.jpg + +--- + +PyBCN is a volunteer association. This page says what personal data this website involves, why we have it, who else sees it, and how to ask us to change or remove it. We wrote it to be read, so it is short. If something is not covered here, ask us. + +## Who is responsible + +**Associació Python Barcelona** (CIF G67254045) is the data controller. + +- **Email**: [pybcn@googlegroups.com](mailto:pybcn@googlegroups.com) +- **Registered address**: *pending. The association must add its registered address here before this page is published.* + +The Management Board handles requests about personal data. We have no data protection officer: the law does not require one for an association of our size and activity. + +## What data this site involves, and why + +### People pages + +The site has pages for the people who organise our events, speak at them, mentor at workshops, or collaborate with the association. Each page shows a name, a photograph, a short biography, the role in PyBCN or at an event, and links to the person's own profiles (GitHub, LinkedIn, Twitter, personal site). + +- **Where it comes from**: the person. Each one sent the photograph and wrote or approved the text for publication here. Someone who did not want a photograph did not send one, and the page shows a silhouette instead. +- **Why we have it**: with the person's consent (GDPR article 6.1.a). You can withdraw it at any time, and we remove the page. Withdrawing consent does not affect what was published before. +- **How long we keep it**: until the person asks us to remove it, or until we take the page down ourselves because it is out of date. +- **One thing to know**: the source of this site is a public Git repository on GitHub. When we remove a page, it disappears from the site and from the current version of the repository. The old text remains in the repository history, as with any Git project. Tell us if you also want it gone from there and we will work it out with you. Copies kept by search engines and web archives are outside our control. + +### Forms + +A few pages link to or embed a Google Form: + +- the **membership form**, to become a member of the association; +- the **propose a talk** form, for a talk at a PyBCN meetup; +- the **PyLadies BCN call for proposals** form; +- the **call for proposals** of each PyDay BCN edition (workshops and lightning talks), and the speaker, mentor, and attendee forms of some workshops. + +Each form asks for what it needs to handle your request: usually your name, an email address to answer you, and the content of your proposal or your membership details. + +- **Where it goes**: into a Google Forms spreadsheet in a Google account run by the association's organizers. Google stores it under its own [privacy policy](https://policies.google.com/privacy). +- **Why we have it**: to do what you asked for, which is the membership agreement or the steps you take to propose a talk or join a workshop (GDPR article 6.1.b). +- **Who sees it**: the organizers of that event or working group. +- **How long we keep it**: responses to an event form are needed until the event is over and its programme is published. We have no automatic deletion after that. Ask us and we delete your response. Membership data stays in the member register for as long as you are a member; the law requires associations to keep that register and the related accounting records for some years after. + +### Membership payments + +The membership fee is paid on [PayPal](https://www.paypal.com)'s site through a Subscribe button. PayPal tells us your name, your email address, and the amount paid. We never see your card or bank details. PayPal is a separate controller under its own [privacy statement](https://www.paypal.com/es/legalhub/privacy-full). We keep the payment record because the accounting and tax rules require it. + +### Email + +Our contact addresses, such as pybcn@googlegroups.com and pyladies-bcn@googlegroups.com, are Google Groups. A message you send there is stored in the group and read by the organizers who are members of that group. We use it to answer you and to follow up on what you asked (GDPR article 6.1.b and 6.1.f). The thread stays in the group archive; ask us and we delete it. + +### Embedded Google content + +A few pages embed a Google Form or a Google Calendar in a frame. The frame is served by Google: when the page loads, Google sees your IP address and browser details, and may set its own cookies inside the frame. Google's [privacy policy](https://policies.google.com/privacy) applies to that. + +### Cookies + +This site sets no cookies of its own, and runs no analytics or tracking scripts. Your browser also loads a few images from unsplash.com (page headers) and paypalobjects.com (the PayPal button). Like any image host, those servers see your IP address and browser details. + +### Hosting + +The site is served by [GitHub Pages](https://pages.github.com). GitHub may log the IP address and request details of each visit for security and operation, under the [GitHub privacy statement](https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement). We do not see or receive those logs. + +## Who else sees your data + +Nobody buys or receives your data from us. The companies named above see it because we use their services: Google (forms, calendar, mailing lists, documents), PayPal (payments), and GitHub (hosting and the source repository). All three are based in the USA. Each publishes the safeguards it applies to data from the EU, and we rely on those. + +## Your rights + +You can ask us to: + +- see the data we hold about you (access); +- correct it (rectification); +- delete it (erasure), including a whole people page; +- limit how we use it (restriction), or object to a use (objection); +- give it to you in a usable format (portability); +- withdraw your consent, for a people page or anything else. + +To do so, write to [pybcn@googlegroups.com](mailto:pybcn@googlegroups.com). Say what you want and which page or form it concerns. For a people page, write from the email address or one of the profiles linked on the page, so we know it is you. The law gives us one month to answer. We do it by hand, as volunteers, so a few days is normal. + +If you think we handle your data wrongly, you can complain to the Spanish data protection authority, the [Agencia Española de Protección de Datos](https://www.aepd.es). + +## Changes to this policy + +We may update this policy. Every change is visible in the [history of this page](https://github.com/pybcn/pybcn.github.io/commits/edition/content/pybcn_association/privacy-policy.md) on GitHub. + +Last updated: 2026-10-07 From 7969efd92ddd88371097d573ebbe143ad5088f17 Mon Sep 17 00:00:00 2001 From: David Arcos Date: Wed, 7 Oct 2026 11:12:24 +0200 Subject: [PATCH 4/8] Link the legal notice and the privacy policy from the footer The footer is where a reader looks for them. The two pages are resolved with site.GetPage, so a moved or renamed page fails the build instead of leaving a dead link. --- themes/pybcn_theme/assets/scss/footer.scss | 10 ++++++++++ themes/pybcn_theme/layouts/partials/footer.html | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/themes/pybcn_theme/assets/scss/footer.scss b/themes/pybcn_theme/assets/scss/footer.scss index efd3b77e..f891013a 100644 --- a/themes/pybcn_theme/assets/scss/footer.scss +++ b/themes/pybcn_theme/assets/scss/footer.scss @@ -4,6 +4,16 @@ footer { color: white; margin-top: 30px; + .legal_links { + margin-top: 10px; + text-align: center; + + a { + color: inherit; + text-decoration: underline; + } + } + img.logo_icon { width: 30px; height: auto; diff --git a/themes/pybcn_theme/layouts/partials/footer.html b/themes/pybcn_theme/layouts/partials/footer.html index 69d4a513..50462cce 100644 --- a/themes/pybcn_theme/layouts/partials/footer.html +++ b/themes/pybcn_theme/layouts/partials/footer.html @@ -15,6 +15,15 @@ {{ end }} + {{/* The legal pages are resolved through site.GetPage, so a moved or + renamed page fails the build instead of leaving a dead link. */}} +
+ +
{{ end }} \ No newline at end of file From 64d0aff67bb6083b6feaa16a9cff3fc14b91c68e Mon Sep 17 00:00:00 2001 From: David Arcos Date: Wed, 7 Oct 2026 11:12:44 +0200 Subject: [PATCH 5/8] Remove the dead cookie consent banner The partial was included only when cookie_consent_info_url was set, and the site config never set it, so no page rendered the banner. The site sets no cookie of its own, which the privacy policy now states. A banner that asks consent for a cookie that does not exist would only mislead, so the partial and the two vendored Osano assets go. --- .../assets/css/cookieconsent.min.css | 6 ---- .../assets/js/cookieconsent.min.js | 1 - .../layouts/partials/cookie-consent.html | 28 ------------------- themes/pybcn_theme/layouts/partials/head.html | 3 -- 4 files changed, 38 deletions(-) delete mode 100644 themes/pybcn_theme/assets/css/cookieconsent.min.css delete mode 100644 themes/pybcn_theme/assets/js/cookieconsent.min.js delete mode 100644 themes/pybcn_theme/layouts/partials/cookie-consent.html diff --git a/themes/pybcn_theme/assets/css/cookieconsent.min.css b/themes/pybcn_theme/assets/css/cookieconsent.min.css deleted file mode 100644 index d4d43902..00000000 --- a/themes/pybcn_theme/assets/css/cookieconsent.min.css +++ /dev/null @@ -1,6 +0,0 @@ -.cc-window{opacity:1;-webkit-transition:opacity 1s ease;transition:opacity 1s ease}.cc-window.cc-invisible{opacity:0}.cc-animate.cc-revoke{-webkit-transition:transform 1s ease;-webkit-transition:-webkit-transform 1s ease;transition:-webkit-transform 1s ease;transition:transform 1s ease;transition:transform 1s ease,-webkit-transform 1s ease}.cc-animate.cc-revoke.cc-top{-webkit-transform:translateY(-2em);transform:translateY(-2em)}.cc-animate.cc-revoke.cc-bottom{-webkit-transform:translateY(2em);transform:translateY(2em)}.cc-animate.cc-revoke.cc-active.cc-top{-webkit-transform:translateY(0);transform:translateY(0)}.cc-animate.cc-revoke.cc-active.cc-bottom{-webkit-transform:translateY(0);transform:translateY(0)}.cc-revoke:hover{-webkit-transform:translateY(0);transform:translateY(0)}.cc-grower{max-height:0;overflow:hidden;-webkit-transition:max-height 1s;transition:max-height 1s} -.cc-revoke,.cc-window{position:fixed;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;font-family:Helvetica,Calibri,Arial,sans-serif;font-size:16px;line-height:1.5em;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;z-index:9999}.cc-window.cc-static{position:static}.cc-window.cc-floating{padding:2em;max-width:24em;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner{padding:1em 1.8em;width:100%;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.cc-revoke{padding:.5em}.cc-revoke:hover{text-decoration:underline}.cc-header{font-size:18px;font-weight:700}.cc-btn,.cc-close,.cc-link,.cc-revoke{cursor:pointer}.cc-link{opacity:.8;display:inline-block;padding:.2em;text-decoration:underline}.cc-link:hover{opacity:1}.cc-link:active,.cc-link:visited{color:initial}.cc-btn{display:block;padding:.4em .8em;font-size:.9em;font-weight:700;border-width:2px;border-style:solid;text-align:center;white-space:nowrap}.cc-highlight .cc-btn:first-child{background-color:transparent;border-color:transparent}.cc-highlight .cc-btn:first-child:focus,.cc-highlight .cc-btn:first-child:hover{background-color:transparent;text-decoration:underline}.cc-close{display:block;position:absolute;top:.5em;right:.5em;font-size:1.6em;opacity:.9;line-height:.75}.cc-close:focus,.cc-close:hover{opacity:1} -.cc-revoke.cc-top{top:0;left:3em;border-bottom-left-radius:.5em;border-bottom-right-radius:.5em}.cc-revoke.cc-bottom{bottom:0;left:3em;border-top-left-radius:.5em;border-top-right-radius:.5em}.cc-revoke.cc-left{left:3em;right:unset}.cc-revoke.cc-right{right:3em;left:unset}.cc-top{top:1em}.cc-left{left:1em}.cc-right{right:1em}.cc-bottom{bottom:1em}.cc-floating>.cc-link{margin-bottom:1em}.cc-floating .cc-message{display:block;margin-bottom:1em}.cc-window.cc-floating .cc-compliance{-webkit-box-flex:1;-ms-flex:1 0 auto;flex:1 0 auto}.cc-window.cc-banner{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.cc-banner.cc-top{left:0;right:0;top:0}.cc-banner.cc-bottom{left:0;right:0;bottom:0}.cc-banner .cc-message{display:block;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;max-width:100%;margin-right:1em}.cc-compliance{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-line-pack:justify;align-content:space-between}.cc-floating .cc-compliance>.cc-btn{-webkit-box-flex:1;-ms-flex:1;flex:1}.cc-btn+.cc-btn{margin-left:.5em} -@media print{.cc-revoke,.cc-window{display:none}}@media screen and (max-width:900px){.cc-btn{white-space:normal}}@media screen and (max-width:414px) and (orientation:portrait),screen and (max-width:736px) and (orientation:landscape){.cc-window.cc-top{top:0}.cc-window.cc-bottom{bottom:0}.cc-window.cc-banner,.cc-window.cc-floating,.cc-window.cc-left,.cc-window.cc-right{left:0;right:0}.cc-window.cc-banner{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.cc-window.cc-banner .cc-compliance{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto}.cc-window.cc-floating{max-width:none}.cc-window .cc-message{margin-bottom:1em}.cc-window.cc-banner{-webkit-box-align:unset;-ms-flex-align:unset;align-items:unset}.cc-window.cc-banner .cc-message{margin-right:0}} -.cc-floating.cc-theme-classic{padding:1.2em;border-radius:5px}.cc-floating.cc-type-info.cc-theme-classic .cc-compliance{text-align:center;display:inline;-webkit-box-flex:0;-ms-flex:none;flex:none}.cc-theme-classic .cc-btn{border-radius:5px}.cc-theme-classic .cc-btn:last-child{min-width:140px}.cc-floating.cc-type-info.cc-theme-classic .cc-btn{display:inline-block} -.cc-theme-edgeless.cc-window{padding:0}.cc-floating.cc-theme-edgeless .cc-message{margin:2em;margin-bottom:1.5em}.cc-banner.cc-theme-edgeless .cc-btn{margin:0;padding:.8em 1.8em;height:100%}.cc-banner.cc-theme-edgeless .cc-message{margin-left:1em}.cc-floating.cc-theme-edgeless .cc-btn+.cc-btn{margin-left:0} \ No newline at end of file diff --git a/themes/pybcn_theme/assets/js/cookieconsent.min.js b/themes/pybcn_theme/assets/js/cookieconsent.min.js deleted file mode 100644 index 1e3dccf1..00000000 --- a/themes/pybcn_theme/assets/js/cookieconsent.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){if(!e.hasInitialised){var t={escapeRegExp:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},hasClass:function(e,t){var i=" ";return 1===e.nodeType&&(i+e.className+i).replace(/[\n\t]/g,i).indexOf(i+t+i)>=0},addClass:function(e,t){e.className+=" "+t},removeClass:function(e,t){var i=new RegExp("\\b"+this.escapeRegExp(t)+"\\b");e.className=e.className.replace(i,"")},interpolateString:function(e,t){return e.replace(/{{([a-z][a-z0-9\-_]*)}}/gi,function(e){return t(arguments[1])||""})},getCookie:function(e){var t=("; "+document.cookie).split("; "+e+"=");return t.length<2?void 0:t.pop().split(";").shift()},setCookie:function(e,t,i,n,o,s){var r=new Date;r.setHours(r.getHours()+24*(i||365));var a=[e+"="+t,"expires="+r.toUTCString(),"path="+(o||"/")];n&&a.push("domain="+n),s&&a.push("secure"),document.cookie=a.join(";")},deepExtend:function(e,t){for(var i in t)t.hasOwnProperty(i)&&(i in e&&this.isPlainObject(e[i])&&this.isPlainObject(t[i])?this.deepExtend(e[i],t[i]):e[i]=t[i]);return e},throttle:function(e,t){var i=!1;return function(){i||(e.apply(this,arguments),i=!0,setTimeout(function(){i=!1},t))}},hash:function(e){var t,i,n=0;if(0===e.length)return n;for(t=0,i=e.length;t=128?"#000":"#fff"},getLuminance:function(e){var t=parseInt(this.normaliseHex(e),16),i=38+(t>>16),n=38+(t>>8&255),o=38+(255&t);return"#"+(16777216+65536*(i<255?i<1?0:i:255)+256*(n<255?n<1?0:n:255)+(o<255?o<1?0:o:255)).toString(16).slice(1)},isMobile:function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)},isPlainObject:function(e){return"object"==typeof e&&null!==e&&e.constructor==Object},traverseDOMPath:function(e,i){return e&&e.parentNode?t.hasClass(e,i)?e:this.traverseDOMPath(e.parentNode,i):null}};e.status={deny:"deny",allow:"allow",dismiss:"dismiss"},e.transitionEnd=function(){var e=document.createElement("div"),t={t:"transitionend",OT:"oTransitionEnd",msT:"MSTransitionEnd",MozT:"transitionend",WebkitT:"webkitTransitionEnd"};for(var i in t)if(t.hasOwnProperty(i)&&void 0!==e.style[i+"ransition"])return t[i];return""}(),e.hasTransition=!!e.transitionEnd;var i=Object.keys(e.status).map(t.escapeRegExp);e.customStyles={},e.Popup=function(){var n={enabled:!0,container:null,cookie:{name:"cookieconsent_status",path:"/",domain:"",expiryDays:365,secure:!1},onPopupOpen:function(){},onPopupClose:function(){},onInitialise:function(e){},onStatusChange:function(e,t){},onRevokeChoice:function(){},onNoCookieLaw:function(e,t){},content:{header:"Cookies used on the website!",message:"This website uses cookies to ensure you get the best experience on our website.",dismiss:"Got it!",allow:"Allow cookies",deny:"Decline",link:"Learn more",href:"https://www.cookiesandyou.com",close:"❌",target:"_blank",policy:"Cookie Policy"},elements:{header:'{{header}} ',message:'{{message}}',messagelink:'{{message}} {{link}}',dismiss:'{{dismiss}}',allow:'{{allow}}',deny:'{{deny}}',link:'{{link}}',close:'{{close}}'},window:'',revokeBtn:'
{{policy}}
',compliance:{info:'
{{dismiss}}
',"opt-in":'
{{deny}}{{allow}}
',"opt-out":'
{{deny}}{{allow}}
'},type:"info",layouts:{basic:"{{messagelink}}{{compliance}}","basic-close":"{{messagelink}}{{compliance}}{{close}}","basic-header":"{{header}}{{message}}{{link}}{{compliance}}"},layout:"basic",position:"bottom",theme:"block",static:!1,palette:null,revokable:!1,animateRevokable:!0,showLink:!0,dismissOnScroll:!1,dismissOnTimeout:!1,dismissOnWindowClick:!1,ignoreClicksFrom:["cc-revoke","cc-btn"],autoOpen:!0,autoAttach:!0,whitelistPage:[],blacklistPage:[],overrideHTML:null};function o(){this.initialise.apply(this,arguments)}function s(e){this.openingTimeout=null,t.removeClass(e,"cc-invisible")}function r(t){t.style.display="none",t.removeEventListener(e.transitionEnd,this.afterTransition),this.afterTransition=null}function a(){var e=this.options.position.split("-"),t=[];return e.forEach(function(e){t.push("cc-"+e)}),t}function c(n){var o=this.options,s=document.createElement("div"),r=o.container&&1===o.container.nodeType?o.container:document.body;s.innerHTML=n;var a=s.children[0];return a.style.display="none",t.hasClass(a,"cc-window")&&e.hasTransition&&t.addClass(a,"cc-invisible"),this.onButtonClick=function(n){var o=t.traverseDOMPath(n.target,"cc-btn")||n.target;if(t.hasClass(o,"cc-btn")){var s=o.className.match(new RegExp("\\bcc-("+i.join("|")+")\\b")),r=s&&s[1]||!1;r&&(this.setStatus(r),this.close(!0))}t.hasClass(o,"cc-close")&&(this.setStatus(e.status.dismiss),this.close(!0));t.hasClass(o,"cc-revoke")&&this.revokeChoice()}.bind(this),a.addEventListener("click",this.onButtonClick),o.autoAttach&&(r.firstChild?r.insertBefore(a,r.firstChild):r.appendChild(a)),a}function l(e){return"000000"==(e=t.normaliseHex(e))?"#222":t.getLuminance(e)}function u(e,t){for(var i=0,n=e.length;i=0;o&&t(n);return o}.call(this)&&(this.options.enabled=!1),u(this.options.blacklistPage,location.pathname)&&(this.options.enabled=!1),u(this.options.whitelistPage,location.pathname)&&(this.options.enabled=!0);var o=this.options.window.replace("{{classes}}",function(){var i=this.options,n="top"==i.position||"bottom"==i.position?"banner":"floating";t.isMobile()&&(n="floating");var o=["cc-"+n,"cc-type-"+i.type,"cc-theme-"+i.theme];i.static&&o.push("cc-static");o.push.apply(o,a.call(this));(function(i){var n=t.hash(JSON.stringify(i)),o="cc-color-override-"+n,s=t.isPlainObject(i);this.customStyleSelector=s?o:null,s&&function(i,n,o){if(e.customStyles[i])return void++e.customStyles[i].references;var s={},r=n.popup,a=n.button,c=n.highlight;r&&(r.text=r.text?r.text:t.getContrast(r.background),r.link=r.link?r.link:r.text,s[o+".cc-window"]=["color: "+r.text,"background-color: "+r.background],s[o+".cc-revoke"]=["color: "+r.text,"background-color: "+r.background],s[o+" .cc-link,"+o+" .cc-link:active,"+o+" .cc-link:visited"]=["color: "+r.link],a&&(a.text=a.text?a.text:t.getContrast(a.background),a.border=a.border?a.border:"transparent",s[o+" .cc-btn"]=["color: "+a.text,"border-color: "+a.border,"background-color: "+a.background],a.padding&&s[o+" .cc-btn"].push("padding: "+a.padding),"transparent"!=a.background&&(s[o+" .cc-btn:hover, "+o+" .cc-btn:focus"]=["background-color: "+(a.hover||l(a.background))]),c?(c.text=c.text?c.text:t.getContrast(c.background),c.border=c.border?c.border:"transparent",s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+c.text,"border-color: "+c.border,"background-color: "+c.background]):s[o+" .cc-highlight .cc-btn:first-child"]=["color: "+r.text]));var u=document.createElement("style");document.head.appendChild(u),e.customStyles[i]={references:1,element:u.sheet};var h=-1;for(var p in s)s.hasOwnProperty(p)&&u.sheet.insertRule(p+"{"+s[p].join(";")+"}",++h)}(n,i,"."+o);return s}).call(this,this.options.palette);this.customStyleSelector&&o.push(this.customStyleSelector);return o}.call(this).join(" ")).replace("{{children}}",function(){var e={},i=this.options;i.showLink||(i.elements.link="",i.elements.messagelink=i.elements.message);Object.keys(i.elements).forEach(function(n){e[n]=t.interpolateString(i.elements[n],function(e){var t=i.content[e];return e&&"string"==typeof t&&t.length?t:""})});var n=i.compliance[i.type];n||(n=i.compliance.info);e.compliance=t.interpolateString(n,function(t){return e[t]});var o=i.layouts[i.layout];o||(o=i.layouts.basic);return t.interpolateString(o,function(t){return e[t]})}.call(this)),s=this.options.overrideHTML;if("string"==typeof s&&s.length&&(o=s),this.options.static){var r=c.call(this,'
'+o+"
");r.style.display="",this.element=r.firstChild,this.element.style.display="none",t.addClass(this.element,"cc-invisible")}else this.element=c.call(this,o);(function(){var i=this.setStatus.bind(this),n=this.close.bind(this),o=this.options.dismissOnTimeout;"number"==typeof o&&o>=0&&(this.dismissTimeout=window.setTimeout(function(){i(e.status.dismiss),n(!0)},Math.floor(o)));var s=this.options.dismissOnScroll;if("number"==typeof s&&s>=0){var r=function(t){window.pageYOffset>Math.floor(s)&&(i(e.status.dismiss),n(!0),window.removeEventListener("scroll",r),this.onWindowScroll=null)};this.options.enabled&&(this.onWindowScroll=r,window.addEventListener("scroll",r))}var a=this.options.dismissOnWindowClick,c=this.options.ignoreClicksFrom;if(a){var l=function(o){for(var s=!1,r=o.path.length,a=c.length,u=0;uo&&(i=!0),i?t.hasClass(n,"cc-active")||t.addClass(n,"cc-active"):t.hasClass(n,"cc-active")&&t.removeClass(n,"cc-active")},200);this.onMouseMove=o,window.addEventListener("mousemove",o)}}}.call(this),this.options.autoOpen&&this.autoOpen()},o.prototype.destroy=function(){this.onButtonClick&&this.element&&(this.element.removeEventListener("click",this.onButtonClick),this.onButtonClick=null),this.dismissTimeout&&(clearTimeout(this.dismissTimeout),this.dismissTimeout=null),this.onWindowScroll&&(window.removeEventListener("scroll",this.onWindowScroll),this.onWindowScroll=null),this.onWindowClick&&(window.removeEventListener("click",this.onWindowClick),this.onWindowClick=null),this.onMouseMove&&(window.removeEventListener("mousemove",this.onMouseMove),this.onMouseMove=null),this.element&&this.element.parentNode&&this.element.parentNode.removeChild(this.element),this.element=null,this.revokeBtn&&this.revokeBtn.parentNode&&this.revokeBtn.parentNode.removeChild(this.revokeBtn),this.revokeBtn=null,function(i){if(t.isPlainObject(i)){var n=t.hash(JSON.stringify(i)),o=e.customStyles[n];if(o&&!--o.references){var s=o.element.ownerNode;s&&s.parentNode&&s.parentNode.removeChild(s),e.customStyles[n]=null}}}(this.options.palette),this.options=null},o.prototype.open=function(t){if(this.element)return this.isOpen()||(e.hasTransition?this.fadeIn():this.element.style.display="",this.options.revokable&&this.toggleRevokeButton(),this.options.onPopupOpen.call(this)),this},o.prototype.close=function(t){if(this.element)return this.isOpen()&&(e.hasTransition?this.fadeOut():this.element.style.display="none",t&&this.options.revokable&&this.toggleRevokeButton(!0),this.options.onPopupClose.call(this)),this},o.prototype.fadeIn=function(){var i=this.element;if(e.hasTransition&&i&&(this.afterTransition&&r.call(this,i),t.hasClass(i,"cc-invisible"))){if(i.style.display="",this.options.static){var n=this.element.clientHeight;this.element.parentNode.style.maxHeight=n+"px"}this.openingTimeout=setTimeout(s.bind(this,i),20)}},o.prototype.fadeOut=function(){var i=this.element;e.hasTransition&&i&&(this.openingTimeout&&(clearTimeout(this.openingTimeout),s.bind(this,i)),t.hasClass(i,"cc-invisible")||(this.options.static&&(this.element.parentNode.style.maxHeight=""),this.afterTransition=r.bind(this,i),i.addEventListener(e.transitionEnd,this.afterTransition),t.addClass(i,"cc-invisible")))},o.prototype.isOpen=function(){return this.element&&""==this.element.style.display&&(!e.hasTransition||!t.hasClass(this.element,"cc-invisible"))},o.prototype.toggleRevokeButton=function(e){this.revokeBtn&&(this.revokeBtn.style.display=e?"":"none")},o.prototype.revokeChoice=function(e){this.options.enabled=!0,this.clearStatus(),this.options.onRevokeChoice.call(this),e||this.autoOpen()},o.prototype.hasAnswered=function(t){return Object.keys(e.status).indexOf(this.getStatus())>=0},o.prototype.hasConsented=function(t){var i=this.getStatus();return i==e.status.allow||i==e.status.dismiss},o.prototype.autoOpen=function(e){!this.hasAnswered()&&this.options.enabled?this.open():this.hasAnswered()&&this.options.revokable&&this.toggleRevokeButton(!0)},o.prototype.setStatus=function(i){var n=this.options.cookie,o=t.getCookie(n.name),s=Object.keys(e.status).indexOf(o)>=0;Object.keys(e.status).indexOf(i)>=0?(t.setCookie(n.name,i,n.expiryDays,n.domain,n.path,n.secure),this.options.onStatusChange.call(this,i,s)):this.clearStatus()},o.prototype.getStatus=function(){return t.getCookie(this.options.cookie.name)},o.prototype.clearStatus=function(){var e=this.options.cookie;t.setCookie(e.name,"",-1,e.domain,e.path)},o}(),e.Location=function(){var e={timeout:5e3,services:["ipinfo"],serviceDefinitions:{ipinfo:function(){return{url:"//ipinfo.io",headers:["Accept: application/json"],callback:function(e,t){try{var i=JSON.parse(t);return i.error?s(i):{code:i.country}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},ipinfodb:function(e){return{url:"//api.ipinfodb.com/v3/ip-country/?key={api_key}&format=json&callback={callback}",isScript:!0,callback:function(e,t){try{var i=JSON.parse(t);return"ERROR"==i.statusCode?s({error:i.statusMessage}):{code:i.countryCode}}catch(e){return s({error:"Invalid response ("+e+")"})}}}},maxmind:function(){return{url:"//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js",isScript:!0,callback:function(e){window.geoip2?geoip2.country(function(t){try{e({code:t.country.iso_code})}catch(t){e(s(t))}},function(t){e(s(t))}):e(new Error("Unexpected response format. The downloaded script should have exported `geoip2` to the global scope"))}}}}};function i(i){t.deepExtend(this.options={},e),t.isPlainObject(i)&&t.deepExtend(this.options,i),this.currentServiceIndex=-1}function n(e,t,i){var n,o=document.createElement("script");o.type="text/"+(e.type||"javascript"),o.src=e.src||e,o.async=!1,o.onreadystatechange=o.onload=function(){var e=o.readyState;clearTimeout(n),t.done||e&&!/loaded|complete/.test(e)||(t.done=!0,t(),o.onreadystatechange=o.onload=null)},document.body.appendChild(o),n=setTimeout(function(){t.done=!0,t(),o.onreadystatechange=o.onload=null},i)}function o(e,t,i,n,o){var s=new(window.XMLHttpRequest||window.ActiveXObject)("MSXML2.XMLHTTP.3.0");if(s.open(n?"POST":"GET",e,1),s.setRequestHeader("Content-type","application/x-www-form-urlencoded"),Array.isArray(o))for(var r=0,a=o.length;r3&&t(s)}),s.send(n)}function s(e){return new Error("Error ["+(e.code||"UNKNOWN")+"]: "+e.error)}return i.prototype.getNextService=function(){var e;do{e=this.getServiceByIdx(++this.currentServiceIndex)}while(this.currentServiceIndex=0,revokable:t.revokable.indexOf(e)>=0,explicitAction:t.explicitAction.indexOf(e)>=0}},i.prototype.applyLaw=function(e,t){var i=this.get(t);return i.hasLaw||(e.enabled=!1,"function"==typeof e.onNoCookieLaw&&e.onNoCookieLaw(t,i)),this.options.regionalLaw&&(i.revokable&&(e.revokable=!0),i.explicitAction&&(e.dismissOnScroll=!1,e.dismissOnTimeout=!1)),e},i}(),e.initialise=function(i,n,o){var s=new e.Law(i.law);n||(n=function(){}),o||(o=function(){});var r=Object.keys(e.status),a=t.getCookie("cookieconsent_status");r.indexOf(a)>=0?n(new e.Popup(i)):e.getCountryCode(i,function(t){delete i.law,delete i.location,t.code&&(i=s.applyLaw(i,t.code)),n(new e.Popup(i))},function(t){delete i.law,delete i.location,o(t,new e.Popup(i))})},e.getCountryCode=function(t,i,n){t.law&&t.law.countryCode?i({code:t.law.countryCode}):t.location?new e.Location(t.location).locate(function(e){i(e||{})},n):i({})},e.utils=t,e.hasInitialised=!0,window.cookieconsent=e}}(window.cookieconsent||{}); \ No newline at end of file diff --git a/themes/pybcn_theme/layouts/partials/cookie-consent.html b/themes/pybcn_theme/layouts/partials/cookie-consent.html deleted file mode 100644 index 6fed6bd4..00000000 --- a/themes/pybcn_theme/layouts/partials/cookie-consent.html +++ /dev/null @@ -1,28 +0,0 @@ -{{ $cookieConsentStyle := resources.Get "css/cookieconsent.min.css" | resources.Fingerprint }} - -{{ $cookieConsentScript := resources.Get "js/cookieconsent.min.js" | resources.Fingerprint }} - - - - -{{- /* vim: set ts=2 sw=2 et: */}} diff --git a/themes/pybcn_theme/layouts/partials/head.html b/themes/pybcn_theme/layouts/partials/head.html index 9319e2df..5fc04290 100644 --- a/themes/pybcn_theme/layouts/partials/head.html +++ b/themes/pybcn_theme/layouts/partials/head.html @@ -35,6 +35,3 @@ {{ end -}} - {{ if .Site.Params.cookie_consent_info_url }} - {{ partial "cookie-consent.html" . }} - {{ end }} From c4791a294d275fe3f78098a8d60e77c048c6a2e3 Mon Sep 17 00:00:00 2001 From: David Arcos Date: Wed, 7 Oct 2026 11:13:01 +0200 Subject: [PATCH 6/8] Drop the cookie banner bullet from the theme README The banner was removed in the previous commit. --- themes/pybcn_theme/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/themes/pybcn_theme/README.md b/themes/pybcn_theme/README.md index 82ee70f3..4a6a874f 100644 --- a/themes/pybcn_theme/README.md +++ b/themes/pybcn_theme/README.md @@ -11,7 +11,6 @@ Based on https://github.com/alanorth/hugo-theme-bootstrap4-blog - Supports Google, Bing, and Yandex site verification via meta tags - Supports Google Analytics (async version), see [Hugo docs](https://gohugo.io/extras/analytics/) - Supports Disqus comments, see [Hugo docs](https://gohugo.io/extras/comments/) -- Can show a message about cookie usage to the user, see [`exampleSite/config.toml`](https://github.com/alanorth/hugo-theme-bootstrap4-blog/blob/master/exampleSite/config.toml) - Allow addition of custom `` code in site's `layouts/partials/head-custom.html` (see [#17](https://github.com/alanorth/hugo-theme-bootstrap4-blog/pull/17)) - Configurable display of summaries of content in list templates. - Configurable keywords for every post From 6126dad46d43ad93544e8a0d826382feaa0c4174 Mon Sep 17 00:00:00 2001 From: David Arcos Date: Thu, 8 Oct 2026 10:40:43 +0200 Subject: [PATCH 7/8] Read who the association is from the configuration The legal notice held the five facts LSSI-CE article 10 asks for as text, two of them a paragraph saying the association still had to supply them. They come from [params.association] now, through a shortcode. The association can correct a fact without a volunteer editing a page of legal prose, which is the kind of edit that goes wrong. And an empty value prints a line that says so rather than a missing bullet: a missing bullet reads as a page that never claimed to carry the fact, where a line that says it is missing is the page admitting it does not yet do its job. Both states are checked in the build. With the two keys empty the page reads "Registered address: not published yet. The Management Board has to supply it." With them filled it reads the value. --- content/pybcn_association/legal-notice.md | 6 +---- layouts/shortcodes/association-identity.html | 27 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 layouts/shortcodes/association-identity.html diff --git a/content/pybcn_association/legal-notice.md b/content/pybcn_association/legal-notice.md index f57f1e5e..952f9100 100644 --- a/content/pybcn_association/legal-notice.md +++ b/content/pybcn_association/legal-notice.md @@ -17,11 +17,7 @@ This website, [pybcn.org](https://pybcn.org), is run by **Associació Python Bar ## Who we are -- **Name**: Associació Python Barcelona -- **Tax ID (CIF)**: G67254045 -- **Registered address**: *pending. The association must add its registered address here before this page is published.* -- **Registry**: *pending. The registration number in the Registre d'Associacions de la Generalitat de Catalunya must be added here before this page is published.* -- **Email**: [pybcn@googlegroups.com](mailto:pybcn@googlegroups.com) +{{< association-identity >}} The Management Board is responsible for this website. You can see who sits on it on the [Information](/pybcn_association/information/) page. diff --git a/layouts/shortcodes/association-identity.html b/layouts/shortcodes/association-identity.html new file mode 100644 index 00000000..efe06e97 --- /dev/null +++ b/layouts/shortcodes/association-identity.html @@ -0,0 +1,27 @@ +{{- /* + Who the association is in law, as a list, for the legal notice. + + Takes no argument. Everything comes from [params.association] in + config.toml and from the main contact email beside it. + + Spanish law 34/2002, LSSI-CE article 10, asks a site run by an + association for its name, its address, an email, its entry in the + register it is recorded in, and its tax number. They are read from the + configuration and not written into the page, so the association can + correct one of them without a volunteer editing a page of legal prose. + See the comment on [params.association] for the rest of the reasoning. + + A value that is empty prints as a line that says so, in the page, rather + than as a missing bullet. A missing bullet reads as a page that never + claimed to carry the fact; a line that says the fact is missing is the + page admitting it does not yet do its job. bin/check-content warns about + the same two keys on every run. +*/ -}} +{{- $a := site.Params.association -}} +
    +
  • Name: {{ $a.legal_name }}
  • +
  • Tax ID (CIF): {{ $a.tax_id }}
  • +
  • Registered address: {{ with $a.address }}{{ . }}{{ else }}not published yet. The Management Board has to supply it.{{ end }}
  • +
  • Registry: {{ with $a.registry }}{{ . }}{{ else }}not published yet. The entry in the Registre d'Associacions de la Generalitat de Catalunya has to come from the Management Board.{{ end }}
  • +
  • Email: {{ site.Params.main_contact_email }}
  • +
From 8ac79ec149be871def66ced180fdb7c32b487d30 Mon Sep 17 00:00:00 2001 From: Daniel Mesejo Date: Thu, 8 Oct 2026 13:24:47 +0200 Subject: [PATCH 8/8] Fill in the registered address and the register entry Both values come from the association's entry in the Registre d'Entitats de la Generalitat de Catalunya, which is public open data at https://analisi.transparenciacatalunya.cat/d/y6fz-g3ff. The entry also confirms the legal name and the tax number already in the configuration. The registry value names the register and not only the number. LSSI-CE article 10 asks for the entry in the register the association is recorded in, and a bare number names no register. The registration date is not asked for, but it is what the register itself prints, so the legal notice shows it on the same line when it is set. The comment on [params.association] and the check-content docstring said the two keys were empty and only the Management Board could fill them. They are filled, and the comment now says where the values come from. The warning on an empty value stays, for the day one is emptied. Co-Authored-By: Claude Fable 5.1 --- bin/check-content | 6 +++--- config.toml | 20 +++++++++++++------- layouts/shortcodes/association-identity.html | 4 +++- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/bin/check-content b/bin/check-content index aaf3758c..c3a51dae 100755 --- a/bin/check-content +++ b/bin/check-content @@ -362,9 +362,9 @@ def check_association(): """The legal notice reads who the association is from config.toml. Two of those facts are not a volunteer's to write: the registered address - and the entry in the register of associations. They start empty, and this - says so on every run rather than letting the legal notice go out with a - gap in the one section the law asks for. + and the entry in the register of associations. Should either be emptied, + this says so on every run rather than letting the legal notice go out + with a gap in the one section the law asks for. A warning and not an error: the site builds and serves fine without them, and an error would turn every pull request red for a reason no diff --git a/config.toml b/config.toml index d962745f..6ce8b873 100644 --- a/config.toml +++ b/config.toml @@ -40,16 +40,22 @@ unsafe=true # here rather than holding them in its own text, so that the association # can correct a fact without a volunteer editing a page of legal prose. # - # address and registry are empty and only the Management Board can fill - # them. bin/check-content reports an empty one as a warning. The legal - # notice page cannot be published while they are empty: the page is the - # one place the law asks for them, and a page that leaves them out does - # not do the job it exists for. + # The values match the association's entry in the Registre d'Entitats de + # la Generalitat de Catalunya, which is public open data: + # https://analisi.transparenciacatalunya.cat/d/y6fz-g3ff + # Only the Management Board changes address, registry or registered_on: + # they describe the association as the register records it, not as + # volunteers know it. The register names the register itself, not only + # the number, because article 10 asks for the entry in the register and a + # bare number names no register. bin/check-content reports an empty + # address or registry as a warning. The legal notice page cannot be + # published while either is empty: the page is the one place the law + # asks for them, and a page that leaves them out does not do its job. [params.association] legal_name = "Associació Python Barcelona" tax_id = "G67254045" - address = "" - registry = "" + address = "Carrer de Concepció Arenal, 165, 08027 Barcelona" + registry = "Registre d'Associacions de la Generalitat de Catalunya, núm. 64158" main_contact_name_pyladies = "PyLadiesBCN Organizers" main_contact_email_pyladies = "pyladies-bcn@googlegroups.com" diff --git a/layouts/shortcodes/association-identity.html b/layouts/shortcodes/association-identity.html index efe06e97..70db41d9 100644 --- a/layouts/shortcodes/association-identity.html +++ b/layouts/shortcodes/association-identity.html @@ -9,6 +9,8 @@ register it is recorded in, and its tax number. They are read from the configuration and not written into the page, so the association can correct one of them without a volunteer editing a page of legal prose. + The registration date is not asked for; it goes on the registry line + when it is set, because it is what the register itself prints. See the comment on [params.association] for the rest of the reasoning. A value that is empty prints as a line that says so, in the page, rather @@ -22,6 +24,6 @@
  • Name: {{ $a.legal_name }}
  • Tax ID (CIF): {{ $a.tax_id }}
  • Registered address: {{ with $a.address }}{{ . }}{{ else }}not published yet. The Management Board has to supply it.{{ end }}
  • -
  • Registry: {{ with $a.registry }}{{ . }}{{ else }}not published yet. The entry in the Registre d'Associacions de la Generalitat de Catalunya has to come from the Management Board.{{ end }}
  • +
  • Registry: {{ with $a.registry }}{{ . }}{{ with $a.registered_on }}, registered on {{ . }}{{ end }}{{ else }}not published yet. The entry in the Registre d'Associacions de la Generalitat de Catalunya has to come from the Management Board.{{ end }}
  • Email: {{ site.Params.main_contact_email }}