Add registered action attachment points with rendering control.

Review Request #14667 — Created Nov. 3, 2025 and submitted

Information

Review Board
release-7.1.x

Reviewers

When actions were first introduced, an action could specify an
attachment point that they wanted to render into. These were strings
that corresponded to a template tag call, rendering all actions attached
to that point at that location.

This change builds upon that concept by introducing a formal
registration of attachment points. These provide a level of control for
the rendering and state of any actions placed within them, allowing, for
example, one attachment point to render actions as a list of links and
another to render those same actions as a list of buttons.

Each attachment point has a default renderer that's used if the action
being rendered doesn't specify its own default. The intended approach
going forward is to have actions only specify a renderer if they have a
strong need for certain rendering behavior, but to otherwise leave that
up to the parent action group, attachment point, or to the (coming soon)
placement configuration.

Attachment points may also specify a list of actions to directly
include, in the order included. These may be actions registered to this
attachment point, or they may not be. This allows an attachment point to
easily include a set of actions rendered under the attachment point's
control for special extension use cases.

Unit tests pass.

Tested all current actions in the UI. They all appear and behave as
expected.

Tested with in-progress changes that move Quick Access actions to this
new system, and verified they rendered as expected.

Summary ID
Add registered action attachment points with rendering control.
When actions were first introduced, an action could specify an attachment point that they wanted to render into. These were strings that corresponded to a template tag call, rendering all actions attached to that point at that location. This change builds upon that concept by introducing a formal registration of attachment points. These provide a level of control for the rendering and state of any actions placed within them, allowing, for example, one attachment point to render actions as a list of links and another to render those same actions as a list of buttons. Each attachment point has a default renderer that's used if the action being rendered doesn't specify its own default. The intended approach going forward is to have actions only specify a renderer if they have a strong need for certain rendering behavior, but to otherwise leave that up to the parent action group, attachment point, or to the (coming soon) placement configuration. Attachment points may also specify a list of actions to directly include, in the order included. These may be actions registered to this attachment point, or they may not be. This allows an attachment point to easily include a set of actions rendered under the attachment point's control for special extension use cases.
5de9b8a455d3bff272815ac9a52b0280cbc30486
Description From Last Updated

line too long (85 > 79 characters) Column: 80 Error code: E501

reviewbotreviewbot

Should we enforce that the attachment_point_id can only be one of the values in AttachmentPoint, for security purposes? This is …

maubinmaubin
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

chipx86
maubin
  1. 
      
  2. reviewboard/actions/base.py (Diff revision 2)
     
     
     
     
     
     
     
     
    Show all issues

    Should we enforce that the attachment_point_id can only be one of the values in AttachmentPoint, for security purposes? This is related to my comment on /r/14663, what if an action author wants to set the ID to something malicious.

    I guess we do have the check in the actions_html tag where we return an empty string for actions that aren't registered, maybe that's enough safe guarding? I also can't really tell where we register all the aciton attachment points though, do we only register the default values?

    1. Attachment points aren't restricted to prebuilt locations. Part of this is to allow an extension to define their own attachment point and add actions to it, so they can utilize the same machinery.

      If people have unvetted malicious extensions running on their server, they're already in major trouble.

      There's a new registry that registers the attachment points. We register the defaults but new ones can be registered.

    2. registry.py, ActionAttachmentPointsRegistry.get_defaults() returns an instance for each default one.

  3. 
      
david
  1. Ship It!
  2. 
      
chipx86
maubin
  1. Ship It!
  2. 
      
david
  1. Ship It!
  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to release-7.1.x (2b2587b)