I would like to add a custom button in the right section of a channels entry form in the CMS. The this button needs to go to a custom url of the plugin that I have created. The link should contain entry ID so that I can use this ID in my plugin. Can I add a custom button here?

up vote 12 down vote accepted

You can add custom HTML in exactly the spot you’re hoping to, using the (undocumented) cp.entries.edit.right-pane template hook.

To use it, add this to your plugin’s primary class:

public function init()
{
    craft()->templates->hook('cp.entries.edit.right-pane', function(&$context) {
        /** @var EntryModel $entry **/
        $entry = $context['entry'];

        // Make sure this is the correct section
        if ($entry->sectionId == 5) {
            // Return the button HTML
            $url = UrlHelper::getUrl('some/path/'.$entry->id);
            return '<a href="'.$url.'" class="btn">My Button!</a>';
        }
    });
}
  • 1
    Brad B. Why would you hide such an awesome thing? :) – Krzysztof Boduch Jun 14 '17 at 12:31
  • 1
    In Craft 3 this is now Craft::$app->getView()->hook('cp.entries.edit.details', function(array &$context) ... worked great for me! – natebeaty Aug 8 at 18:27

Not possible, unfortunately – you'll have to use JavaScript/jQuery to hack it in.

See Brad's answer for a canonical solution. It's also possible to use JavaScript/jQuery to accomplish what you want – something like this should do the trick:

$('input[name="revisionNotes"]').before('<a href="'+Craft.getCpUrl('yourcustomroute')+'" class="btn">Button label</a>');

The above will inject a button, just above the revision notes input in the sidebar, pointing to /admin/yourcustomroute.

As for getting the ID, the easiest way to do that is to use jQuery to pull the hidden input named entryId:

var entryId = $('input[type="hidden"][name="entryId"]').val();

Obviously, a new entry that hasn't been saved yet doesn't have an entry ID, so you might want to opt for not rendering the button if jQuery can't find the the hidden input, or if its value is empty. So putting it together:

var entryId = $('input[type="hidden"][name="entryId"]').val();

if (entryId) {
    $('input[name="revisionNotes"]').before('<a href="'+Craft.getCpUrl('yourcustomroute/'+entryId)+'" class="btn">Button label</a>');
}

Note that if the URL should point to an action rather than a CP resource, you can use Craft.getActionUrl() over Craft.getCpUrl(), or if its a frontend resource, you can use Craft.getSiteUrl() instead.

You can run the above command in your browser's console to test it out. To run it with your plugin, you'll need to add it to a JavaScript file included in your plugin's /resources folder, and add the file to Craft's Control Panel like this (in your plugin's main class file):

public function init ()
{
    if (craft()->request->isCpRequest()) {
        craft()->templates->includeJsResource('yourPluginHandle/script.js');
    }
}

For more info on adding JavaScript to Craft's Control Panel, see this thread.

Also, be advised that using this method makes your code entirely dependent on the DOM structure of Craft's Control Panel, which can change at any time, possibly breaking your implementation.

EDIT

It would appear this is possible without resorting to JS hacks after all, as per Brad's answer below. I'll leave this answer up anyway, as it could be a useful proof of concept for injecting HTML into other parts of the Control Panel.

  • Completely not documented, but there is a template hook you can use in craft/app/templates/entries/_edit.html called {% hook "cp.entries.edit.right-pane" %} – Brad Bell Apr 5 '16 at 14:47
  • I suppose I'll add that as an answer. – Brad Bell Apr 5 '16 at 16:30

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.