• 
      

    Split the rendering of JavaScript action models and views.

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

    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.
    64080b45a209b91ad223a0767d2bc35bd728c884
    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

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

    reviewbotreviewbot

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

    reviewbotreviewbot

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

    reviewbotreviewbot

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

    reviewbotreviewbot

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

    reviewbotreviewbot

    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. (12% scanned). Column: 9 Error code: E041

    reviewbotreviewbot
    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?

      1. Yeah. In fact, I'm going to move this into state injected by the template tag, so it's not micro-managed specially.

    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?)

      1. The first renders the models globally (only for top-level). The second renders each view of each action for the attachment point at every level, but injects as page state so it's included later.

        I'll rename.

      2. Oh, and this can be cleaned up after the placement change, because actions won't be in a hierarchy anymore natively, just their rendered placements. So we can have one loop. I'll update that accordingly.

      3. Ignore that. I forgot this all changed with the attachment point change. So this all got rewritten anyway.

    3. 
        
    chipx86
    Review request changed
    Change Summary:
    • Moved attachmentPointID for the JS view into js_view_data so it's serialized like all other options.
    • Clarified some docs.
    • Updated class attributes to use ClassVar.
    • Updated the actions_html template tag to better document the two different rendering passes, and to avoid the actions variable.
    Commits:
    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
    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.
    7e8c747c4b614b28203a4125e5d54bea5aaa4236

    Checks run (1 failed, 1 succeeded)

    flake8 passed.
    JSHint failed.

    JSHint

    chipx86
    Review request changed
    Change Summary:

    Fixed up incorrect naming in my templatetag update. We're rendering HTML, not action models.

    Commits:
    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.
    7e8c747c4b614b28203a4125e5d54bea5aaa4236
    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.
    64080b45a209b91ad223a0767d2bc35bd728c884

    Checks run (1 failed, 1 succeeded)

    flake8 passed.
    JSHint failed.

    JSHint

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