Split the rendering of JavaScript action models and views.

Review Request #14665 — Created Oct. 31, 2025 and updated

Information

Review Board
release-7.1.x

Reviewers

We now have enough support for multiple views for the same action. It's
time to separate out the registration of the models and the views so
there's no longer a one-to-one association.

The new BaseAction.render_model_js() is responsible for writing the
JavaScript to render an action model. Every registered action in Python
will be registered in JavaScript.

The existing BaseAction.render_js() (old name currently kept for
compatibility reasons) will render the view. This is now only called
when the attachment points used on the page, rather than all attachment
points. That's handled in the {% actions_html %} template tag.

The template tag renders the HTML for the attachment point where the
template tag is placed, and then sets up a page injection containing the
JavaScript views. Then, when rendering the JavaScript models, the
injected JavaScript views content will be included.

Some of the design of this change is here to facilitate the upcoming
improvements to attachment points.

Unit tests pass.

Tested that all the actions on the page displayed and worked correctly.

Summary ID
Split the rendering of JavaScript action models and views.
We now have enough support for multiple views for the same action. It's time to separate out the registration of the models and the views so there's no longer a one-to-one association. The new `BaseAction.render_model_js()` is responsible for writing the JavaScript to render an action model. Every registered action in Python will be registered in JavaScript. The existing `BaseAction.render_js()` (old name currently kept for compatibility reasons) will render the view. This is now only called when the attachment points used on the page, rather than all attachment points. That's handled in the `{% actions_html %}` template tag. The template tag renders the HTML for the attachment point where the template tag is placed, and then sets up a page injection containing the JavaScript views. Then, when rendering the JavaScript models, the injected JavaScript views content will be included. Some of the design of this change is here to facilitate the upcoming improvements to attachment points.
ac05257d3e82428a725f410c1bcd8cc5f9766b95
Description From Last Updated

Might as well specify "action's Javascript model" here.

maubinmaubin

We should be more specific here and say "... for action model".

maubinmaubin

The part about setting up the model should be removed from the sentence now.

maubinmaubin

It's a little bit confusing that we assign actions twice and iterate over for action in actions twice. Can we …

daviddavid

Expected a string and instead saw %. Column: 2 Error code: W095

reviewbotreviewbot

Expected ':' and instead saw 'load'. Column: 4 Error code: E021

reviewbotreviewbot

Expected a JSON value. Column: 9 Error code: E003

reviewbotreviewbot

Expected '}' and instead saw 'actions'. Column: 9 Error code: E021

reviewbotreviewbot

Unrecoverable syntax error. (11% scanned). Column: 9 Error code: E041

reviewbotreviewbot

Same comment as the one on /r/14663, should we |escapejs this?

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

JSHint

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

    Might as well specify "action's Javascript model" here.

  3. reviewboard/actions/base.py (Diff revision 1)
     
     
    Show all issues

    We should be more specific here and say "... for action model".

  4. reviewboard/actions/base.py (Diff revision 1)
     
     
    Show all issues

    The part about setting up the model should be removed from the sentence now.

  5. Show all issues

    Same comment as the one on /r/14663, should we |escapejs this?

  6. 
      
david
  1. 
      
  2. reviewboard/actions/templatetags/actions.py (Diff revision 1)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    Show all issues

    It's a little bit confusing that we assign actions twice and iterate over for action in actions twice.

    Can we either just move the get_for_attachment calls into the for lines, or have two different variable names (like toplevel_actions and actions_with_children?)

  3.