Skip to content

Commit

Permalink
Merge branch 'main' into instancebehavior
Browse files Browse the repository at this point in the history
  • Loading branch information
mamico committed Jul 9, 2024
2 parents c4ec3d4 + 9200c6a commit ceabffc
Show file tree
Hide file tree
Showing 40 changed files with 335 additions and 67 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ jobs:
plone-version: "6.0"
- python-version: "3.12"
plone-version: "6.0"
- python-version: "3.10"
plone-version: "6.1"
- python-version: "3.11"
plone-version: "6.1"
- python-version: "3.12"
plone-version: "6.1"
steps:
# git checkout
- uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ docs/.DS_Store
/local
/venv
/.mr.developer.cfg
/.python-version
*.mo
docs/_build
docs/plone.restapi.http-examples
Expand Down
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12
45 changes: 45 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,51 @@ Changelog
.. towncrier release notes start
9.7.1 (2024-06-29)
------------------

Bug fixes:


- Remove use of `portal_properties` in context navigation.
Theoretically we checked `portal_properties.site_properties.sortAttribute`.
[maurits] (#125)


Internal:


- Update test-no-uncommitted-doc-changes to run on Python 3.12 instead of 3.9. @tisto, @davisagli (#1794)


9.7.0 (2024-06-15)
------------------

New features:


- Add cache rules for `@site` and `@navroot`. @mamico (#1779)
- Added TeaserBlockSerializer which updates the contents of a teaser block from its target if the block has `"overwrite": false`. @pbauer, @davisagli (#1788)


Bug fixes:


- Returns an error message when an Invalid error occurs when validating a controlpanel field. Also translates the message. @wesleybl (#1771)
- Users service: Fixed edge case AttributeError if a user is enumerated but doesn't actually exist. @davisagli (#1775)
- Add Plone 6.1 support to classifiers and test against it. @tisto (#1780)
- Make plone.app.discussion an optional dependency (core add-on). @jensens (#1781)
- Fix require plone.app.iterate on test extras. @jensens (#1782)
- Fix require plone.app.upgrade on test extras. @jensens (#1783)


Documentation:


- Fix event start & end timezone in documentation examples. @davisagli (#1776)
- Move sharing endpoint docs to the correct section. @davisagli (#1778)


9.6.1 (2024-04-25)
------------------

Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ exclude Makefile
exclude bootstrap-buildout.py
exclude CODEOWNERS
exclude docs/make.bat
exclude .python-version
recursive-exclude docs/doctrees *
recursive-exclude docs/html *
recursive-exclude performance *
Expand Down
1 change: 0 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ It can be seen in action at the following sites:
- Zeelandia GmbH & Co. KG: https://www.zeelandia.de (by kitconcept GmbH)
- VHS-Ehrenamtsportal: https://vhs-ehrenamtsportal.de (by kitconcept GmbH)
- German Physical Society: https://www.dpg-physik.de (by kitconcept GmbH)
- Universitat Politècnica de Catalunya: https://www.upc.edu/en (by kitconcept GmbH)


Support
Expand Down
2 changes: 1 addition & 1 deletion constraints.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
black == 22.3.0
black == 24.4.2
flake8 == 4.0.1
7 changes: 6 additions & 1 deletion docs/source/endpoints/comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ myst:

# Comments

Plone offers to users a feature to post comments on any content object with `plone.app.discussion`.
```{versionchanged} Plone 6.1
Discussion is disabled by default in Plone 6.1 and later.
To enable discussion, see the Plone 6.1 upgrade guide section {ref}`backend-upgrade-plone-v61-discussion-label`.
```

Discussion is a feature that allows your site visitors to comment on web pages for any content object.

Commenting can be enabled globally for specific content types and for single content objects.

Expand Down
1 change: 1 addition & 0 deletions docs/source/endpoints/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ registry
relations
roles
searching
sharing
site
system
transactions
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion docs/source/usage/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ expansion
exploring
i18n
serialization
sharing
types-schema
blocks
```
1 change: 0 additions & 1 deletion news/1775.bugfix

This file was deleted.

1 change: 0 additions & 1 deletion news/1776.documentation

This file was deleted.

1 change: 0 additions & 1 deletion plone-5.2.x.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ extends =
base.cfg

[versions]
black = 22.3.0

# we need the newest plone.rest release
plone.rest = 3.0.1
Expand Down
3 changes: 1 addition & 2 deletions plone-6.0.x.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[buildout]
extends =
https://dist.plone.org/release/6.0.7/versions.cfg
https://dist.plone.org/release/6.0.11.1/versions.cfg
base.cfg

[buildout:python37]
Expand All @@ -13,7 +13,6 @@ recipe = plone.recipe.zope2instance
zodb-temporary-storage = off

[versions]
black = 22.3.0
pygments = 2.14.0
plone.app.linkintegrity = 4.0.3
robotframework-browser = 17.5.2
Expand Down
15 changes: 15 additions & 0 deletions plone-6.1.x.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[buildout]
extends =
https://dist.plone.org/release/6.1.0a3/versions.cfg
base.cfg

[buildout:python37]
parts =
test
code-analysis

[instance]
recipe = plone.recipe.zope2instance
zodb-temporary-storage = off

[versions]
2 changes: 1 addition & 1 deletion requirements-6.0.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
-r https://dist.plone.org/release/6.0.7/requirements.txt
-r https://dist.plone.org/release/6.0.11.1/requirements.txt
1 change: 1 addition & 0 deletions requirements-6.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-r https://dist.plone.org/release/6.1.0a3/requirements.txt
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys


version = "9.6.2.dev0"
version = "9.7.2.dev0"

if sys.version_info.major == 2:
raise ValueError(
Expand Down Expand Up @@ -43,7 +43,10 @@ def read(filename):
"collective.MockMailHost",
"plone.app.caching",
"plone.app.contenttypes[test]",
"plone.app.iterate",
"plone.app.discussion[test]",
"plone.app.testing",
"plone.app.upgrade",
"plone.api",
"requests",
"mock",
Expand All @@ -62,6 +65,7 @@ def read(filename):
"Framework :: Plone",
"Framework :: Plone :: 5.2",
"Framework :: Plone :: 6.0",
"Framework :: Plone :: 6.1",
"Framework :: Plone :: Core",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
Expand Down
83 changes: 83 additions & 0 deletions src/plone/restapi/serializer/blocks.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from plone import api
from plone.app.uuid.utils import uuidToCatalogBrain
from plone.restapi.bbb import IPloneSiteRoot
from plone.restapi.behaviors import IBlocks
from plone.restapi.blocks import visit_blocks, iter_block_transform_handlers
Expand All @@ -6,17 +8,20 @@
from plone.restapi.deserializer.blocks import transform_links
from plone.restapi.interfaces import IBlockFieldSerializationTransformer
from plone.restapi.interfaces import IFieldSerializer
from plone.restapi.interfaces import ISerializeToJsonSummary
from plone.restapi.serializer.converters import json_compatible
from plone.restapi.serializer.dxfields import DefaultFieldSerializer
from plone.restapi.serializer.utils import resolve_uid, uid_to_url
from plone.schema import IJSONField
from zope.component import adapter
from zope.component import getMultiAdapter
from zope.interface import implementer
from zope.interface import Interface
from zope.publisher.interfaces.browser import IBrowserRequest

import copy
import os
import re


@adapter(IJSONField, IBlocks, Interface)
Expand Down Expand Up @@ -193,3 +198,81 @@ class SlateTableBlockSerializer(SlateTableBlockSerializerBase):
@adapter(IPloneSiteRoot, IBrowserRequest)
class SlateTableBlockSerializerRoot(SlateTableBlockSerializerBase):
"""Serializer for site root"""


class TeaserBlockSerializerBase:
order = 0
block_type = "teaser"

def __init__(self, context, request):
self.context = context
self.request = request

def __call__(self, block):
return self._process_data(block)

def _process_data(self, data, field=None):
value = data.get("href", "")
if value:
if "overwrite" not in data:
# A block without this option is old and keeps the behavior
# where data is not dynamically pulled from the href
data["overwrite"] = True
return data

if isinstance(value, str):
url = value
value = [{"@id": url}]
else:
url = value[0].get("@id", "")
brain = url_to_brain(url)
if brain is not None:
serialized_brain = getMultiAdapter(
(brain, self.request), ISerializeToJsonSummary
)()

if not data.get("overwrite"):
# Update fields at the top level of the block data
for key in ["title", "description", "head_title"]:
if key in serialized_brain:
data[key] = serialized_brain[key]

# We return the serialized brain.
value[0].update(serialized_brain)
data["href"] = value
elif not url.startswith("http"):
# Source not found; clear out derived fields
data["href"] = []
return data


@implementer(IBlockFieldSerializationTransformer)
@adapter(IBlocks, IBrowserRequest)
class TeaserBlockSerializer(TeaserBlockSerializerBase):
"""Serializer for content-types with IBlocks behavior"""


RESOLVE_UID_REGEXP = re.compile("resolveuid/([^/]+)")


@implementer(IBlockFieldSerializationTransformer)
@adapter(IPloneSiteRoot, IBrowserRequest)
class TeaserBlockSerializerRoot(TeaserBlockSerializerBase):
"""Serializer for site root"""


def url_to_brain(url):
if not url:
return
brain = None
if match := RESOLVE_UID_REGEXP.search(url):
uid = match.group(1)
brain = uuidToCatalogBrain(uid)
else:
# fallback in case the url wasn't converted to a UID
catalog = api.portal.get_tool("portal_catalog")
path = "/".join(api.portal.get().getPhysicalPath()) + url
results = catalog.searchResults(path={"query": path, "depth": 0})
if results:
brain = results[0]
return brain
14 changes: 12 additions & 2 deletions src/plone/restapi/serializer/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@
provides="plone.restapi.interfaces.IBlockFieldSerializationTransformer"
/>

<subscriber
factory=".blocks.TeaserBlockSerializerRoot"
provides="plone.restapi.interfaces.IBlockFieldSerializationTransformer"
/>
<subscriber
factory=".blocks.TeaserBlockSerializer"
provides="plone.restapi.interfaces.IBlockFieldSerializationTransformer"
/>

<adapter factory=".converters.date_converter" />
<adapter factory=".converters.decimal_converter" />
Expand Down Expand Up @@ -107,8 +115,10 @@

<adapter factory=".registry.SerializeRegistryToJson" />

<adapter factory=".discussion.ConversationSerializer" />
<adapter factory=".discussion.CommentSerializer" />
<configure zcml:condition="installed plone.app.discussion">
<adapter factory=".discussion.ConversationSerializer" />
<adapter factory=".discussion.CommentSerializer" />
</configure>

<include package=".controlpanels" />

Expand Down
5 changes: 4 additions & 1 deletion src/plone/restapi/services/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
<include package=".controlpanels" />
<include package=".copymove" />
<include package=".database" />
<include package=".discussion" />
<include
package=".discussion"
zcml:condition="installed plone.app.discussion"
/>
<include package=".groups" />
<include package=".navigation" />
<include package=".contextnavigation" />
Expand Down
11 changes: 0 additions & 11 deletions src/plone/restapi/services/contextnavigation/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,9 +625,6 @@ def __init__(self, context, data):
self.context = context
self.data = data

portal_properties = getToolByName(context, "portal_properties")
navtree_properties = getattr(portal_properties, "navtree_properties")

# Acquire a custom nav query if available
customQuery = getattr(context, "getCustomNavQuery", None)
if customQuery is not None and safe_callable(customQuery):
Expand Down Expand Up @@ -668,14 +665,6 @@ def __init__(self, context, data):
# Only list the applicable types
query["portal_type"] = typesToList(context)

# Apply the desired sort
sortAttribute = navtree_properties.getProperty("sortAttribute", None)
if sortAttribute is not None:
query["sort_on"] = sortAttribute
sortOrder = navtree_properties.getProperty("sortOrder", None)
if sortOrder is not None:
query["sort_order"] = sortOrder

# Filter on workflow states, if enabled
registry = getUtility(IRegistry)
navigation_settings = registry.forInterface(INavigationSchema, prefix="plone")
Expand Down
1 change: 1 addition & 0 deletions src/plone/restapi/services/locking/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" Locking
"""

from datetime import datetime
from datetime import timezone
from plone import api
Expand Down
4 changes: 1 addition & 3 deletions src/plone/restapi/services/relations/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,7 @@ def reply(self):
msg = (
"Source and target not found."
if not source_obj and not target_obj
else "Source not found."
if not source_obj
else "Target not found."
else "Source not found." if not source_obj else "Target not found."
)
msg = f"Failed on creating a relation. {msg}"
log.error(f"{msg} {relationdata}")
Expand Down
Loading

0 comments on commit ceabffc

Please sign in to comment.