This is one of the best solutions I have seen so far without using plugins. It is also used by Paypalthe PayPal module.
MagePal/CustomButton/view/adminhtml/layout/sales_order_view.xmlMagePal/CustomButton/view/adminhtml/layout/sales_order_view.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="sales_order_edit">
<block class="MagePal\CustomButton\Block\Adminhtml\Order\View\Buttons" name="custom_buttons" />
</referenceBlock>
</body>
</page>
MagePal/CustomButton/Block/Adminhtml/Order/View/Buttons.phpMagePal/CustomButton/Block/Adminhtml/Order/View/Buttons.php
namespace MagePal\CustomButton\Block\Adminhtml\Order\View;
class Buttons extends \Magento\Sales\Block\Adminhtml\Order\View
{
protected function _construct()
{
parent::_construct();
if(!$this->getOrderId()) {
return $this;
}
$buttonUrl = $this->_urlBuilder->getUrl(
'adminhtml/custombutton/new',
['order_id' => $this->getOrderId()]
);
$this->addButton(
'create_custom_button',
['label' => __('Custom Button'), 'onclick' => 'setLocation(\'' . $buttonUrl . '\')']
);
return $this;
}
}