Skip to content

Implement Recycle Bin #4168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 63 commits into
base: master
Choose a base branch
from
Open

Implement Recycle Bin #4168

wants to merge 63 commits into from

Conversation

rohnsha0
Copy link
Member

@rohnsha0 rohnsha0 commented Apr 29, 2025

ref #2966

to be merged together:-

  • plone.base - #81
  • plone.app.discussion - #264

RecycleBinView
RecycleBinItemView

replaces #4166

@mister-roboto
Copy link

@rohnsha0 thanks for creating this Pull Request and helping to improve Plone!

TL;DR: Finish pushing changes, pass all other checks, then paste a comment:

@jenkins-plone-org please run jobs

To ensure that these changes do not break other parts of Plone, the Plone test suite matrix needs to pass, but it takes 30-60 min. Other CI checks are usually much faster and the Plone Jenkins resources are limited, so when done pushing changes and all other checks pass either start all Jenkins PR jobs yourself, or simply add the comment above in this PR to start all the jobs automatically.

Happy hacking!

@rohnsha0 rohnsha0 mentioned this pull request Apr 29, 2025
Copy link
Contributor

@stevepiercy stevepiercy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor recyclerbin to recyclebin. I missed this on my previous pass.

@stevepiercy
Copy link
Contributor

@rohnsha0 can you check the failing CI checks from meta? Let us know if you have any questions about it.

@stevepiercy
Copy link
Contributor

stevepiercy commented Apr 29, 2025

@rohnsha0 here's one problem.

https://github.com/plone/Products.CMFPlone/actions/runs/14733219302/job/41352593835?pr=4168#step:7:70

error: cannot format Products/CMFPlone/browser/recyclebin.py: Cannot parse for target version Python 3.8: 77:67:         message = f"{restored_count} item{'s' if deleted_count != 1} restored successfully."

I think we need to change that, as it appears to have support only since Python 3.12, according to PEP 701. Bummer.

Confirmed by https://github.com/plone/Products.CMFPlone/actions/runs/14733219302/job/41352596237?pr=4168#step:7:773.

@rohnsha0
Copy link
Member Author

rohnsha0 commented May 6, 2025

hmmm... strangely the jenkins complains of news entry...

edit: also noticed the same issue in a volto PR, see plone/volto#5090 (comment)

@rohnsha0
Copy link
Member Author

rohnsha0 commented May 6, 2025

also i am not sure how to test PR from plone.base and this pr together :(

@stevepiercy
Copy link
Contributor

Jenkins or mr-roboto's change log verifier are not well. @gforcada @plone/ai-team can you look into the failure?

See also:

@petschki
Copy link
Member

petschki commented May 7, 2025

also i am not sure how to test PR from plone.base and this pr together :(

If you login to jenkins.plone.org you can visit this link https://jenkins.plone.org/job/pull-request-6.2-3.10/build?delay=0sec (or go to the "Pull Request 6.x" Job and klick "Build with Parameters" in the menu on the left) ... now you have a textfield where you enter every PR url you want to include in your job ... each line an url.

NOTE: the state of the jenkins jobs are reported back to the PRs automatically ... you see it in the checklist on the bottom)

@ale-rt
Copy link
Member

ale-rt commented May 8, 2025

I left some comments in another PR that got closed #4166 (comment)
Did you consider them @rohnsha0?

@rohnsha0
Copy link
Member Author

rohnsha0 commented May 9, 2025

I left some comments in another PR that got closed #4166 (comment) Did you consider them @rohnsha0?

i am done implementing z3c.form as suggested. trying to move presentation logics to p.a.layout

@rohnsha0
Copy link
Member Author

rohnsha0 commented May 9, 2025

@ale-rt i noticed only core presentations are placed in p.a.layout. i did not find any controlpanel thing in there... i am not super sure what to do!

@jensens
Copy link
Member

jensens commented May 9, 2025

@ale-rt i noticed only core presentations are placed in p.a.layout. i did not find any controlpanel thing in there... i am not super sure what to do!

Controlpanel goes into https://github.com/plone/Products.CMFPlone/tree/master/Products/CMFPlone/controlpanel/browser

@davisagli
Copy link
Member

Hi @rohnsha0 -- thanks for your diligent work so far.

Tomorrow I plan to test some edge cases. I will also record a video to show to a UX expert our company works with, to see if he has any suggestions.

try:
settings = self._get_settings()
return settings.recycling_enabled
except (KeyError, AttributeError):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can raise zope.interface.interfaces.ComponentLookupError when this is called while the Plone site is being deleted, so we should also catch that here.

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 181, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 390, in publish_module
  Module ZPublisher.WSGIPublisher, line 284, in publish
  Module ZPublisher.mapply, line 98, in mapply
  Module ZPublisher.WSGIPublisher, line 68, in call_object
  Module OFS.ObjectManager, line 560, in manage_delObjects
  Module OFS.ObjectManager, line 417, in _delObject
  Module zope.event, line 33, in notify
  Module zope.component.event, line 27, in dispatch
  Module zope.component._api, line 146, in subscribers
  Module zope.interface.registry, line 458, in subscribers
  Module zope.interface.adapter, line 918, in subscribers
  Module zope.component.event, line 37, in objectEventNotify
  Module zope.component._api, line 146, in subscribers
  Module zope.interface.registry, line 458, in subscribers
  Module zope.interface.adapter, line 918, in subscribers
  Module Products.CMFPlone.events, line 60, in handle_content_removal
  Module Products.CMFPlone.recyclebin, line 164, in is_enabled
  Module Products.CMFPlone.recyclebin, line 156, in _get_settings
  Module zope.component._api, line 180, in getUtility
zope.interface.interfaces.ComponentLookupError: (<InterfaceClass plone.registry.interfaces.IRegistry>, '')

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in fa502d9

@rohnsha0 rohnsha0 requested a review from davisagli May 30, 2025 02:02
Copy link
Contributor

@stevepiercy stevepiercy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor tweaks and a general question about translations and localization of various forms of plurality


message = translate(
_(
"${count} item(s) restored successfully.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know there's a way to use plurals intelligently in translations, but I don't know what that would be. Here's my clueless English attempt.

There might also be something else to handle plurals in translations, but my memory fails me. Here is some reference material.

Perhaps @erral has a better idea of how to support localized singular and plural forms?

Suggested change
"${count} item(s) restored successfully.",
"${count} item{count != 1 ? "s"} restored successfully.",

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pluralisation does not work. I tried it, and I just literally get this in the browser:

1 item${count != 1 ? 's'} restored successfully.

When I extract messages with i18ndude, the po files contain this:

msgid "${count} item${count != 1 ? 's'} restored successfully."

You can't really translate that.

zope.i18n has support for plural messages, but this has not been hooked up in Plone as far as I know. Also, it would need changes in i18ndude.

So: it would be nice to have pluralisation at some point, but currently it does not work.


message = translate(
_(
"${count} item(s) permanently deleted.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flagging for pluralization.


message = translate(
_(
"Recycle bin emptied. ${count} item(s) permanently deleted.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flagging for pluralization.

<div class="d-flex justify-content-between align-items-center flex-wrap gap-2">
<div class="btn-group" role="group">
<button type="submit" name="form.buttons.restore" class="btn btn-primary" i18n:translate="">
<span class="ms-1">Restore Selected</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<span class="ms-1">Restore Selected</span>
<span class="ms-1">Restore selected</span>

<span class="ms-1">Restore Selected</span>
</button>
<button type="submit" name="form.buttons.delete" class="btn btn-danger" i18n:translate="">
<span class="ms-1">Delete Selected</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<span class="ms-1">Delete Selected</span>
<span class="ms-1">Delete selected</span>

class="btn btn-outline-danger"
onclick="return confirm(recyclebinEmptyMessage);"
i18n:translate="">
<span class="ms-1">Empty Recycle Bin</span>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<span class="ms-1">Empty Recycle Bin</span>
<span class="ms-1">Empty recycle bin</span>

Comment on lines +205 to +207
return f'Comment thread: "{comment_preview}" ({comment_count} comments)'
else:
return f"Comment thread ({comment_count} comments)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have two possible plurals to handle here.

… bin.

This avoids having a strange acquisition chain after the item is restored,
which then causes a 'has already been deleted' message if you try to delete it again.
@davisagli
Copy link
Member

@rohnsha0 Here's another thing that didn't quite work like I expected: I created a folder with a page inside, and deleted the folder. Then in the recycle bin I selected the folder and clicked the "Delete Selected" button to delete it permanently. I expected that this would include all children, but afterward the recycle bin still contained the page.

@rohnsha0
Copy link
Member Author

rohnsha0 commented Jun 17, 2025

@rohnsha0 Here's another thing that didn't quite work like I expected: I created a folder with a page inside, and deleted the folder. Then in the recycle bin I selected the folder and clicked the "Delete Selected" button to delete it permanently. I expected that this would include all children, but afterward the recycle bin still contained the page.

@davisagli I fixed it, tested it locally and it now works

edit: also included a testcase covering the same!

@rohnsha0
Copy link
Member Author

@jenkins-plone-org please run jobs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants