• Resolved alttextai

    (@alttextai)


    Hi – we have a situation where more than one plugin (ours and another one) are trying to extend the same backbone view template using Javascript. Basically what’s happening is that the JS on the page has two different calls to: wp.media.view.Attachment.Details = wp.media.view.Attachment.Details.extend({ ... )} .

    This results in what seems like only the last call being the one that actually runs. Is there any way to deal with another plugin also extending a view template that you also want to extend?

Viewing 4 replies - 1 through 4 (of 4 total)
  • Sara

    (@sarayourfriend)

    Can you share a method to reproduce this situation? It would seem like two separate instances of that expression should work. The second .extend would be calling it on the result of the first call, not the original Attachment.Details, so they “should” build off of each other in series, unless they are somehow interfering with each other. Seeing the specific situation and being able to debug it would help find an answer.

    Thread Starter alttextai

    (@alttextai)

    Sure here’s a simple example. Just put this code in a JS file that’s added on every admin page:

      function extendMediaTemplate() {
    wp.media.view.Attachment.Details = wp.media.view.Attachment.Details.extend({
    template: function (view) {
    const html = wp.media.template('attachment-details')(view);

    console.log("TEMPLATE EXTEND: " + Date.now().toString());

    return html;
    }
    });
    }

    document.addEventListener('DOMContentLoaded', () => {
    if (!wp?.media?.view?.Attachment?.Details) {
    return;
    }

    extendMediaTemplate();

    setTimeout(extendMediaTemplate, 500);
    });

    Then to trigger it, edit a post, click on the “Set featured image” box in the gutenberg editor, then select the Media Library tab, and then click on one of the images from the media library.

    In the browser console, you’ll see just *one* of the console.log() statements be printed. It should be printing both if the two template extend methods are being executed (one immediately, the other after the timeout fires).

    Sara

    (@sarayourfriend)

    Gotcha, thanks for the code, that helped a lot.

    The issue in your code is that it extends, but never calls the parent model’s template function. That’s a problem if there are other plugins extending the same model, because your code will never run theirs (even though it is indeed extending that model). Backbone does not automatically merge the results of the parent model’s template with that of the extended model.

    Here’s an example of code that does work with multiple extensions of the same model:

    function someOtherPlugin() {
    wp.media.view.Attachment.Details = wp.media.view.Attachment.Details.extend({
    template: function (view) {
    console.log("some other plugin template: " + Date.now().toString());
    const html = wp.media.template('attachment-details')(view);

    return '<div id="other-plugin-extend-details"></div>' + html;
    }
    });
    }

    function myPluginExtendDetails() {
    const previousAttachmentDetails = wp.media.view.Attachment.Details;
    wp.media.view.Attachment.Details = previousAttachmentDetails.extend({
    template: function (view) {
    const html = previousAttachmentDetails.prototype.template.apply(this, arguments);
    console.log("TEMPLATE EXTEND A: " + Date.now().toString());

    return '<div id="my-plugin-extend-details"></div>' + html;
    }
    });
    }

    document.addEventListener('DOMContentLoaded', () => {
    console.log("and here :)")
    if (!wp?.media?.view?.Attachment?.Details) {
    return;
    }

    someOtherPlugin();
    myPluginExtendDetails();
    });

    The important change is to call template of the “previous” attachment details. Given both instances are assigning to the same wp.media.view.Attachment.Details, you need to cache a reference to the previous wp.media.view.Attachment.Details so you can call its template function during your own extension. Hopefully the other plugin also does this so that the order of execution of the plugins doesn’t cause an issue.

    The above code results in both of the new divs appearing in the attachment details sidebar of the media model in the editor. If you replace the call to previousAttachmentDetails.prototype.template.apply with wp.media.template('attachment-details')(view);, as your reproduction example shows, you’ll see that only the my-plugin-extend-details div appears in the resulting HTML.

    Let me know if that helps, and here’s a link to Backbone’s documentation on the extend function for reference, which includes a note regarding “super” calls in Backbone models.

    Thread Starter alttextai

    (@alttextai)

    @sarayourfriend Thank you for clarifying how this works. Super helpful!

Viewing 4 replies - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.