imio.smartweb.core 1.3.9__py3-none-any.whl → 1.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. imio/smartweb/core/browser/configure.zcml +24 -12
  2. imio/smartweb/core/browser/faceted/map.pt +1 -3
  3. imio/smartweb/core/browser/templates/singlecheckboxbool_hidden.pt +21 -0
  4. imio/smartweb/core/configure.zcml +12 -6
  5. imio/smartweb/core/contents/pages/view_section.pt +1 -2
  6. imio/smartweb/core/profiles/default/metadata.xml +1 -0
  7. imio/smartweb/core/viewlets/ogptags.py +6 -12
  8. imio/smartweb/core/webcomponents/build/js/141.smartweb-webcomponents-compiled.js +1 -1
  9. imio/smartweb/core/webcomponents/build/js/141.smartweb-webcomponents-compiled.js.LICENSE.txt +3 -3
  10. imio/smartweb/core/webcomponents/build/js/21.smartweb-webcomponents-compiled.js +1 -1
  11. imio/smartweb/core/webcomponents/build/js/218.smartweb-webcomponents-compiled.js +1 -1
  12. imio/smartweb/core/webcomponents/build/js/373.smartweb-webcomponents-compiled.js +1 -1
  13. imio/smartweb/core/webcomponents/build/js/486.smartweb-webcomponents-compiled.js +1 -1
  14. imio/smartweb/core/webcomponents/build/js/491.smartweb-webcomponents-compiled.js +2 -0
  15. imio/smartweb/core/webcomponents/build/js/666.smartweb-webcomponents-compiled.js +1 -1
  16. imio/smartweb/core/webcomponents/build/js/824.smartweb-webcomponents-compiled.js +1 -1
  17. imio/smartweb/core/webcomponents/build/js/884.smartweb-webcomponents-compiled.js +1 -1
  18. imio/smartweb/core/webcomponents/build/js/919.smartweb-webcomponents-compiled.js +1 -1
  19. imio/smartweb/core/webcomponents/build/js/922.smartweb-webcomponents-compiled.js +1 -1
  20. imio/smartweb/core/webcomponents/build/js/963.smartweb-webcomponents-compiled.js +1 -1
  21. imio/smartweb/core/webcomponents/build/js/smartweb-webcomponents-compiled.js +1 -1
  22. imio/smartweb/core/webcomponents/src/components/Annuaire/ContactContent/ContactContent.jsx +57 -0
  23. imio/smartweb/core/webcomponents/src/components/Annuaire/ContactList/ContactList.jsx +47 -0
  24. imio/smartweb/core/webcomponents/src/components/Events/EventContent/EventContent.jsx +69 -0
  25. imio/smartweb/core/webcomponents/src/components/Events/EventList/EventList.jsx +47 -0
  26. imio/smartweb/core/webcomponents/src/components/News/NewsContent/NewsContent.jsx +69 -0
  27. imio/smartweb/core/webcomponents/src/components/News/NewsList/NewsList.jsx +48 -0
  28. {imio.smartweb.core-1.3.9.dist-info → imio_smartweb_core-1.4.1.dist-info}/METADATA +58 -8
  29. {imio.smartweb.core-1.3.9.dist-info → imio_smartweb_core-1.4.1.dist-info}/RECORD +36 -35
  30. {imio.smartweb.core-1.3.9.dist-info → imio_smartweb_core-1.4.1.dist-info}/WHEEL +1 -1
  31. imio/smartweb/core/webcomponents/build/js/15.smartweb-webcomponents-compiled.js +0 -2
  32. /imio/smartweb/core/webcomponents/build/js/{15.smartweb-webcomponents-compiled.js.LICENSE.txt → 491.smartweb-webcomponents-compiled.js.LICENSE.txt} +0 -0
  33. /imio.smartweb.core-1.3.9-py3.8-nspkg.pth → /imio.smartweb.core-1.4.1-py3.12-nspkg.pth +0 -0
  34. {imio.smartweb.core-1.3.9.dist-info → imio_smartweb_core-1.4.1.dist-info/licenses}/LICENSE.GPL +0 -0
  35. {imio.smartweb.core-1.3.9.dist-info → imio_smartweb_core-1.4.1.dist-info/licenses}/LICENSE.rst +0 -0
  36. {imio.smartweb.core-1.3.9.dist-info → imio_smartweb_core-1.4.1.dist-info}/namespace_packages.txt +0 -0
  37. {imio.smartweb.core-1.3.9.dist-info → imio_smartweb_core-1.4.1.dist-info}/top_level.txt +0 -0
@@ -61,6 +61,63 @@ const ContactContent = ({ queryUrl, onChange, contextAuthenticatedUser }) => {
61
61
  }
62
62
  }, [item]);
63
63
 
64
+ useEffect(() => {
65
+ if (!item || !item.title) return;
66
+ document.title = item.title;
67
+
68
+ const ogImageWidth = image?.width || "";
69
+ const ogImageHeight = image?.height || "";
70
+
71
+ // Liste complète de toutes les balises possibles
72
+ const allMetaProps = [
73
+ { name: "description" },
74
+ { property: "og:title" },
75
+ { property: "og:description" },
76
+ { property: "og:url" },
77
+ { property: "og:type" },
78
+ { property: "og:image" },
79
+ { property: "og:image:type" },
80
+ { property: "og:image:alt" },
81
+ { property: "og:image:width" },
82
+ { property: "og:image:height" },
83
+ ];
84
+
85
+ // Supprime les anciennes balises
86
+ allMetaProps.forEach(({ name, property }) => {
87
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
88
+ const existing = document.head.querySelector(selector);
89
+ if (existing) {
90
+ document.head.removeChild(existing);
91
+ }
92
+ });
93
+
94
+ // Recrée les balises à jour
95
+ const metaUpdates = [
96
+ { name: "description", content: [item.subtitle, item.description].filter(Boolean).join(" - ") },
97
+ { property: "og:title", content: item.title },
98
+ { property: "og:description", content: [item.subtitle, item.description].filter(Boolean).join(" - ") },
99
+ { property: "og:url", content: typeof window !== "undefined" ? window.location.href : "" },
100
+ { property: "og:type", content: "profile" },
101
+ ];
102
+
103
+ if (item.image_affiche_scale) {
104
+ metaUpdates.push({ property: "og:image", content: item.image_affiche_scale });
105
+
106
+ if (ogImageWidth && ogImageHeight) {
107
+ metaUpdates.push({ property: "og:image:width", content: ogImageWidth });
108
+ metaUpdates.push({ property: "og:image:height", content: ogImageHeight });
109
+ }
110
+ }
111
+
112
+ metaUpdates.forEach(({ name, property, content }) => {
113
+ const tag = document.createElement("meta");
114
+ if (name) tag.setAttribute("name", name);
115
+ if (property) tag.setAttribute("property", property);
116
+ tag.setAttribute("content", content);
117
+ document.head.appendChild(tag);
118
+ });
119
+ }, [item, image]);
120
+
64
121
  // set social link
65
122
  useEffect(() => {
66
123
  item.urls && setSocial(item.urls.filter((urls) => urls.type !== "website"));
@@ -18,6 +18,53 @@ const ContactList = ({ contactArray, onChange, onHover, contextAuthenticatedUser
18
18
  useEffect(() => {
19
19
  window.scrollTo({ top: scrollPos, left: 0, behavior: "instant" });
20
20
  }, [contactArray]);
21
+
22
+ useEffect(() => {
23
+ // Liste complète de toutes les balises possibles
24
+ const allMetaProps = [
25
+ { name: "description" },
26
+ { property: "og:title" },
27
+ { property: "og:description" },
28
+ { property: "og:url" },
29
+ { property: "og:type" },
30
+ { property: "og:image" },
31
+ { property: "og:image:type" },
32
+ { property: "og:image:alt" },
33
+ { property: "og:image:width" },
34
+ { property: "og:image:height" },
35
+ ];
36
+
37
+ // Supprime les anciennes balises
38
+ allMetaProps.forEach(({ name, property }) => {
39
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
40
+ const existing = document.head.querySelector(selector);
41
+ if (existing) {
42
+ document.head.removeChild(existing);
43
+ }
44
+ });
45
+
46
+ const metaUpdates = [
47
+ { name: "description", content: "Annuaire" },
48
+ { property: "og:title", content: "Annuaire" },
49
+ { property: "og:description", content: "Annuaire" },
50
+ { property: "og:url", content: typeof window !== "undefined" ? window.location.href : "" },
51
+ { property: "og:type", content: "website" },
52
+ ];
53
+
54
+ metaUpdates.forEach(({ name, property, content }) => {
55
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
56
+ let tag = document.head.querySelector(selector);
57
+
58
+ if (!tag) {
59
+ tag = document.createElement("meta");
60
+ if (name) tag.setAttribute("name", name);
61
+ if (property) tag.setAttribute("property", property);
62
+ document.head.appendChild(tag);
63
+ }
64
+
65
+ tag.setAttribute("content", content);
66
+ });
67
+ }, []);
21
68
  return (
22
69
  <React.Fragment>
23
70
  <ul className="r-result-list annuaire-result-list">
@@ -22,6 +22,7 @@ const ContactContent = ({ queryUrl, onChange, onlyPastEvents, contextAuthenticat
22
22
  const [recurence, setRecurence] = useState([]);
23
23
  const [files, setFiles] = useState();
24
24
  const [gallery, setGallery] = useState();
25
+ const [image, setImage] = useState();
25
26
  const [isSchedulVisible, setSchedulVisibility] = useState(false);
26
27
  const modalRef = useRef();
27
28
  const { response, error, isLoading } = useAxios(
@@ -75,6 +76,74 @@ const ContactContent = ({ queryUrl, onChange, onlyPastEvents, contextAuthenticat
75
76
  onChange(null);
76
77
  }
77
78
 
79
+ // set image
80
+ useEffect(() => {
81
+ if (item.image_affiche_scale) {
82
+ const img = new Image();
83
+ img.src = item.image_affiche_scale;
84
+ img.onload = () => {
85
+ setImage(img);
86
+ };
87
+ }
88
+ }, [item]);
89
+
90
+ useEffect(() => {
91
+ if (!item || !item.title) return;
92
+ document.title = item.title;
93
+
94
+ const ogImageWidth = image?.width || "";
95
+ const ogImageHeight = image?.height || "";
96
+
97
+ // Liste complète de toutes les balises possibles
98
+ const allMetaProps = [
99
+ { name: "description" },
100
+ { property: "og:title" },
101
+ { property: "og:description" },
102
+ { property: "og:url" },
103
+ { property: "og:type" },
104
+ { property: "og:image" },
105
+ { property: "og:image:type" },
106
+ { property: "og:image:alt" },
107
+ { property: "og:image:width" },
108
+ { property: "og:image:height" },
109
+ ];
110
+
111
+ // Supprime les anciennes balises
112
+ allMetaProps.forEach(({ name, property }) => {
113
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
114
+ const existing = document.head.querySelector(selector);
115
+ if (existing) {
116
+ document.head.removeChild(existing);
117
+ }
118
+ });
119
+
120
+ // Recrée les balises à jour
121
+ const metaUpdates = [
122
+ { name: "description", content: [item.subtitle, item.description].filter(Boolean).join(" - ") },
123
+ { property: "og:title", content: item.title },
124
+ { property: "og:description", content: [item.subtitle, item.description].filter(Boolean).join(" - ") },
125
+ { property: "og:url", content: typeof window !== "undefined" ? window.location.href : "" },
126
+ { property: "og:type", content: "event" },
127
+ ];
128
+
129
+ if (item.image_affiche_scale) {
130
+ metaUpdates.push({ property: "og:image", content: item.image_affiche_scale });
131
+
132
+ if (ogImageWidth && ogImageHeight) {
133
+ metaUpdates.push({ property: "og:image:width", content: ogImageWidth });
134
+ metaUpdates.push({ property: "og:image:height", content: ogImageHeight });
135
+ }
136
+ }
137
+
138
+ metaUpdates.forEach(({ name, property, content }) => {
139
+ const tag = document.createElement("meta");
140
+ if (name) tag.setAttribute("name", name);
141
+ if (property) tag.setAttribute("property", property);
142
+ tag.setAttribute("content", content);
143
+ document.head.appendChild(tag);
144
+ });
145
+ }, [item, image]);
146
+
78
147
  // ref to toggle
79
148
 
80
149
  useEffect(() => {
@@ -25,6 +25,53 @@ const ContactList = ({
25
25
  window.scrollTo({ top: scrollPos, left: 0, behavior: "instant" });
26
26
  }, [itemsArray]);
27
27
 
28
+ useEffect(() => {
29
+ // Liste complète de toutes les balises possibles
30
+ const allMetaProps = [
31
+ { name: "description" },
32
+ { property: "og:title" },
33
+ { property: "og:description" },
34
+ { property: "og:url" },
35
+ { property: "og:type" },
36
+ { property: "og:image" },
37
+ { property: "og:image:type" },
38
+ { property: "og:image:alt" },
39
+ { property: "og:image:width" },
40
+ { property: "og:image:height" },
41
+ ];
42
+
43
+ // Supprime les anciennes balises
44
+ allMetaProps.forEach(({ name, property }) => {
45
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
46
+ const existing = document.head.querySelector(selector);
47
+ if (existing) {
48
+ document.head.removeChild(existing);
49
+ }
50
+ });
51
+
52
+ const metaUpdates = [
53
+ { name: "description", content: "Agenda" },
54
+ { property: "og:title", content: "Agenda" },
55
+ { property: "og:description", content: "Agenda" },
56
+ { property: "og:url", content: typeof window !== "undefined" ? window.location.href : "" },
57
+ { property: "og:type", content: "website" },
58
+ ];
59
+
60
+ metaUpdates.forEach(({ name, property, content }) => {
61
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
62
+ let tag = document.head.querySelector(selector);
63
+
64
+ if (!tag) {
65
+ tag = document.createElement("meta");
66
+ if (name) tag.setAttribute("name", name);
67
+ if (property) tag.setAttribute("property", property);
68
+ document.head.appendChild(tag);
69
+ }
70
+
71
+ tag.setAttribute("content", content);
72
+ });
73
+ }, []);
74
+
28
75
  return (
29
76
  <React.Fragment>
30
77
  <ul className="r-result-list event-result-list">
@@ -17,6 +17,7 @@ const ContactContent = ({ queryUrl, onChange, contextAuthenticatedUser }) => {
17
17
  const [params, setParams] = useState(parsed2);
18
18
  const [item, setitem] = useState({});
19
19
  const [files, setFiles] = useState(null);
20
+ const [image, setImage] = useState();
20
21
  const [gallery, setGallery] = useState();
21
22
  const { response, error, isLoading } = useAxios(
22
23
  {
@@ -71,6 +72,74 @@ const ContactContent = ({ queryUrl, onChange, contextAuthenticatedUser }) => {
71
72
  const created = moment(item.created).startOf("minute").fromNow();
72
73
  const lastModified = moment(item.modified).startOf("minute").fromNow();
73
74
 
75
+ // set image
76
+ useEffect(() => {
77
+ if (item.image_affiche_scale) {
78
+ const img = new Image();
79
+ img.src = item.image_affiche_scale;
80
+ img.onload = () => {
81
+ setImage(img);
82
+ };
83
+ }
84
+ }, [item]);
85
+
86
+ useEffect(() => {
87
+ if (!item || !item.title) return;
88
+ document.title = item.title;
89
+
90
+ const ogImageWidth = image?.width || "";
91
+ const ogImageHeight = image?.height || "";
92
+
93
+ // Liste complète de toutes les balises possibles
94
+ const allMetaProps = [
95
+ { name: "description" },
96
+ { property: "og:title" },
97
+ { property: "og:description" },
98
+ { property: "og:url" },
99
+ { property: "og:type" },
100
+ { property: "og:image" },
101
+ { property: "og:image:type" },
102
+ { property: "og:image:alt" },
103
+ { property: "og:image:width" },
104
+ { property: "og:image:height" },
105
+ ];
106
+
107
+ // Supprime les anciennes balises
108
+ allMetaProps.forEach(({ name, property }) => {
109
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
110
+ const existing = document.head.querySelector(selector);
111
+ if (existing) {
112
+ document.head.removeChild(existing);
113
+ }
114
+ });
115
+
116
+ // Recrée les balises à jour
117
+ const metaUpdates = [
118
+ { name: "description", content: [item.subtitle, item.description].filter(Boolean).join(" - ") },
119
+ { property: "og:title", content: item.title },
120
+ { property: "og:description", content: [item.subtitle, item.description].filter(Boolean).join(" - ") },
121
+ { property: "og:url", content: typeof window !== "undefined" ? window.location.href : "" },
122
+ { property: "og:type", content: "event" },
123
+ ];
124
+
125
+ if (item.image_affiche_scale) {
126
+ metaUpdates.push({ property: "og:image", content: item.image_affiche_scale });
127
+
128
+ if (ogImageWidth && ogImageHeight) {
129
+ metaUpdates.push({ property: "og:image:width", content: ogImageWidth });
130
+ metaUpdates.push({ property: "og:image:height", content: ogImageHeight });
131
+ }
132
+ }
133
+
134
+ metaUpdates.forEach(({ name, property, content }) => {
135
+ const tag = document.createElement("meta");
136
+ if (name) tag.setAttribute("name", name);
137
+ if (property) tag.setAttribute("property", property);
138
+ tag.setAttribute("content", content);
139
+ document.head.appendChild(tag);
140
+ });
141
+ }, [item, image]);
142
+
74
143
  return isLoading ? (
75
144
  <div className="lds-roller-container">
76
145
  <Translate text="Chargement..." />
@@ -14,6 +14,54 @@ const NewsList = ({ itemsArray, onChange, showCategoriesOrTopics, contextAuthent
14
14
  useEffect(() => {
15
15
  window.scrollTo({ top: scrollPos, left: 0, behavior: "instant" });
16
16
  }, [itemsArray]);
17
+
18
+ useEffect(() => {
19
+ // Liste complète de toutes les balises possibles
20
+ const allMetaProps = [
21
+ { name: "description" },
22
+ { property: "og:title" },
23
+ { property: "og:description" },
24
+ { property: "og:url" },
25
+ { property: "og:type" },
26
+ { property: "og:image" },
27
+ { property: "og:image:type" },
28
+ { property: "og:image:alt" },
29
+ { property: "og:image:width" },
30
+ { property: "og:image:height" },
31
+ ];
32
+
33
+ // Supprime les anciennes balises
34
+ allMetaProps.forEach(({ name, property }) => {
35
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
36
+ const existing = document.head.querySelector(selector);
37
+ if (existing) {
38
+ document.head.removeChild(existing);
39
+ }
40
+ });
41
+
42
+ const metaUpdates = [
43
+ { name: "description", content: "Actualités" },
44
+ { property: "og:title", content: "Actualités" },
45
+ { property: "og:description", content: "Actualtés" },
46
+ { property: "og:url", content: typeof window !== "undefined" ? window.location.href : "" },
47
+ { property: "og:type", content: "website" },
48
+ ];
49
+
50
+ metaUpdates.forEach(({ name, property, content }) => {
51
+ const selector = name ? `meta[name="${name}"]` : `meta[property="${property}"]`;
52
+ let tag = document.head.querySelector(selector);
53
+
54
+ if (!tag) {
55
+ tag = document.createElement("meta");
56
+ if (name) tag.setAttribute("name", name);
57
+ if (property) tag.setAttribute("property", property);
58
+ document.head.appendChild(tag);
59
+ }
60
+
61
+ tag.setAttribute("content", content);
62
+ });
63
+ }, []);
64
+
17
65
  return (
18
66
  <React.Fragment>
19
67
  <ul className="r-result-list actu-result-list">
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: imio.smartweb.core
3
- Version: 1.3.9
3
+ Version: 1.4.1
4
4
  Summary: Core product for iMio websites
5
5
  Home-page: https://github.com/imio/imio.smartweb.core
6
6
  Author: Christophe Boulanger
@@ -15,11 +15,13 @@ Classifier: Environment :: Web Environment
15
15
  Classifier: Framework :: Plone
16
16
  Classifier: Framework :: Plone :: Addon
17
17
  Classifier: Framework :: Plone :: 6.0
18
+ Classifier: Framework :: Plone :: 6.1
18
19
  Classifier: Programming Language :: Python
19
20
  Classifier: Programming Language :: Python :: 3
20
21
  Classifier: Programming Language :: Python :: 3.10
21
22
  Classifier: Programming Language :: Python :: 3.11
22
23
  Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
23
25
  Classifier: Operating System :: OS Independent
24
26
  Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
25
27
  Requires-Python: >=3.10
@@ -29,6 +31,7 @@ Requires-Dist: setuptools
29
31
  Requires-Dist: z3c.jbot
30
32
  Requires-Dist: z3c.unconfigure
31
33
  Requires-Dist: plone.api>=1.8.4
34
+ Requires-Dist: plone.app.discussion
32
35
  Requires-Dist: plone.gallery
33
36
  Requires-Dist: plone.restapi
34
37
  Requires-Dist: plone.app.dexterity
@@ -49,6 +52,7 @@ Requires-Dist: more-itertools
49
52
  Requires-Dist: imio.smartweb.common
50
53
  Requires-Dist: imio.smartweb.locales
51
54
  Provides-Extra: test
55
+ Requires-Dist: mock; extra == "test"
52
56
  Requires-Dist: plone.app.testing; extra == "test"
53
57
  Requires-Dist: plone.testing>=5.0.0; extra == "test"
54
58
  Requires-Dist: plone.app.contenttypes; extra == "test"
@@ -57,6 +61,19 @@ Requires-Dist: plone.restapi[test]; extra == "test"
57
61
  Requires-Dist: requests-mock; extra == "test"
58
62
  Requires-Dist: beautifulsoup4; extra == "test"
59
63
  Requires-Dist: freezegun; extra == "test"
64
+ Dynamic: author
65
+ Dynamic: author-email
66
+ Dynamic: classifier
67
+ Dynamic: description
68
+ Dynamic: home-page
69
+ Dynamic: keywords
70
+ Dynamic: license
71
+ Dynamic: license-file
72
+ Dynamic: project-url
73
+ Dynamic: provides-extra
74
+ Dynamic: requires-dist
75
+ Dynamic: requires-python
76
+ Dynamic: summary
60
77
 
61
78
  .. This README is meant for consumption by humans and pypi. Pypi can render rst files so please do not use Sphinx features.
62
79
  If you want to learn more about writing documentation, please check out: http://docs.plone.org/about/documentation_styleguide.html
@@ -191,6 +208,39 @@ Changelog
191
208
  =========
192
209
 
193
210
 
211
+ 1.4.1 (2025-05-14)
212
+ ------------------
213
+
214
+ - WEB-4165 : Add the React script to manage og tags in other views (Agenda / News)
215
+ [boulch]
216
+
217
+ - WEB-4165 : Refactoring : Don't use react-helmet/react-helmet-async anymore to manage og tags in directory view
218
+ because of duplicated og:tags. Favor for creating og:tags in header viewlet (SSR) and update it thanks to REACT script
219
+ [boulch]
220
+
221
+ - WEB-4165 : Add react-helmet pakcage (6.1.0) to manage og tags in directory view
222
+ [boulch]
223
+
224
+
225
+ 1.4 (2025-05-06)
226
+ ----------------
227
+
228
+ - Override singlecheckboxtool_hidden.pt to restore the "hidden" type to the hidden checkboxes
229
+ This is a temporary fix, we will issue a PR to fix this en plone.app.z3cform
230
+ See https://github.com/plone/plone.app.z3cform/commit/6351cf60d408d4a76743741db45093c8e5a1c4de
231
+ [remdub]
232
+
233
+ - GHA tests on Python 3.10 3.11, 3.12 and 3.13
234
+ [remdub]
235
+
236
+ - Update Python classifiers to be compatible with Plone 6.1 and Python 3.13
237
+ [remdub]
238
+
239
+ - Remove obsolete and unused portal_properties in view_section template
240
+ PropertiesTool is removed in Plone 6.1
241
+ [bsuttor, remdub]
242
+
243
+
194
244
  1.3.9 (2025-04-23)
195
245
  ------------------
196
246
 
@@ -261,7 +311,7 @@ Changelog
261
311
  Prevent some basic stupid and wicked attack
262
312
  [boulch]
263
313
 
264
- - Ideabox : Add status for vote
314
+ - Ideabox : Add status for vote
265
315
  [thomlamb]
266
316
 
267
317
 
@@ -288,7 +338,7 @@ Changelog
288
338
  [thomlamb]
289
339
 
290
340
  - WEB-4231 : Prevent issues in research when default (agenda, news, directory) views objects were removed
291
- [boulch]
341
+ [boulch]
292
342
 
293
343
 
294
344
  1.3 (2025-03-04)
@@ -429,7 +479,7 @@ Changelog
429
479
  -------------------
430
480
 
431
481
  - WEB-4199 : Fix missing contacts when there are more contacts than default Plone batching
432
- [boulch]
482
+ [boulch]
433
483
 
434
484
  - Replace url by social icon in contact section
435
485
  [thomlamb]
@@ -476,11 +526,11 @@ Changelog
476
526
 
477
527
  - WEB-4024 : Add React event files size
478
528
  [thomlamb]
479
-
480
- - WEB-4027 : Add linkedin icon and change Twitter icon to X icon
529
+
530
+ - WEB-4027 : Add linkedin icon and change Twitter icon to X icon
481
531
  [thomlamb]
482
532
 
483
- - WEB-4146 : Replace created by effective date in news cards
533
+ - WEB-4146 : Replace created by effective date in news cards
484
534
  [thomlamb]
485
535
 
486
536