4

I'm trying to add content to Magento 2 Admin page; specifically the "Order and Account" section of the Information page in "Order View".

I've done the following but my content is not rendering

  1. created my_module (this is working - I see it in enabled modules and other functions are working)
  2. Created layout file within my_module

    <?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>
        <referenceContainer name="content">
            <block class="Magento\Sales\Block\Adminhtml\Order\View\Info" name="my_module_name" template="my_module::list.phtml"/>
        </referenceContainer>
    </body>
</page>
  1. Created template file within my_module (my\module\view\adminhtml\templates\list.phtml)

<?php ?>

<h1><?php echo __('Latest Orders') ?></h1> <?php /** @var $post \\Model\Post */ echo 'hello';?>

The above template does not appear on the Order admin page. What am I doing wrong?

2
  • Did you clear your cache?
    – scrowler
    Commented Dec 17, 2015 at 3:00
  • @user20719, is it working?
    – Bojjaiah
    Commented Dec 17, 2015 at 9:03

7 Answers 7

12

try this

Learning/RewriteSales/Block/Adminhtml/Order/View/Custom.php

<?php
namespace Learning\RewriteSales\Block\Adminhtml\Order\View;
class Custom extends \Magento\Backend\Block\Template
{

}

Learning/RewriteSales/view/adminhtml/layout/sales_order_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>      
        <referenceBlock name="order_info">
            <block class="Learning\RewriteSales\Block\Adminhtml\Order\View\Custom" name="sales_order_view_custom" template="order/view/custom.phtml" />
        </referenceBlock>
    </body>
</page>

Learning/RewriteSales/view/adminhtml/templates/order/view/custom.phtml

<h1>Hi, I am here!</h1>

clear the cache and run it.

14
  • ,I updated but still not render & then added "echo 'hello'; exit;" to see if hitting code but does not even exit "My\Module\view\adminhtml\layout\order_info.xml" (removed page tag due to length here) <body> <referenceBlock name="order_info"> <block class="My\Module\Block\Adminhtml\View\Info" name="my_module_view_custom" template="list.phtml"/> </referenceBlock> </body> </page> "My\Order\Block\Adminhtml\View\Info.php": <?php namespace My\Module\Adminhtml\View; echo 'here';exit: class Info extends \Magento\Backend\Block\Template { }
    – user20719
    Commented Dec 17, 2015 at 20:47
  • @user20719, layout name should be sales_order_view.xml, not order_info.xml. So change/rename it order_info.xml to sales_order_view.xml.
    – Bojjaiah
    Commented Dec 18, 2015 at 3:50
  • I decided to just cut and paste your sample and of course that worked!! Thanks for your help!
    – user20719
    Commented Dec 18, 2015 at 19:05
  • i have followed steps.but it's not showing anything.even i tried to change in core file but no change.
    – vijay b
    Commented Mar 9, 2017 at 7:32
  • 1
    @Haris Use code <?php $_order = $block->getOrder() ?>
    – Bojjaiah
    Commented Mar 4, 2020 at 6:01
12

in the first look the block Magento\Sales\Block\Adminhtml\Order\View\Info have function :

protected function _beforeToHtml()
{
    if (!$this->getParentBlock()) {
        throw new \Magento\Framework\Exception\LocalizedException(
            __('Please correct the parent block for this block.')
        );
    }
    $this->setOrder($this->getParentBlock()->getOrder());

    foreach ($this->getParentBlock()->getOrderInfoData() as $key => $value) {
        $this->setDataUsingMethod($key, $value);
    }

    parent::_beforeToHtml();
}

you can't call directly inside container ,it need have a parent block i think the best way for inject your block , you need use the additional container with name payment_additional_info because all sub block inside tab , render specific childs , if you go to default sales_order_view.xml of sales module you will find:

    <block class="Magento\Sales\Block\Adminhtml\Order\View\Tabs" name="sales_order_tabs">
        <block class="Magento\Sales\Block\Adminhtml\Order\View\Tab\Info" name="order_tab_info" template="order/view/tab/info.phtml">
            <block class="Magento\Sales\Block\Adminhtml\Order\View\Messages" name="order_messages"/>
            <block class="Magento\Sales\Block\Adminhtml\Order\View\Info" name="order_info" template="order/view/info.phtml"/>
            <block class="Magento\Sales\Block\Adminhtml\Order\View\Items" name="order_items" template="order/view/items.phtml">
                <block class="Magento\Sales\Block\Adminhtml\Order\View\Items\Renderer\DefaultRenderer" as="default" template="order/view/items/renderer/default.phtml"/>
                <block class="Magento\Sales\Block\Adminhtml\Items\Column\Qty" name="column_qty" template="items/column/qty.phtml" group="column"/>
                <block class="Magento\Sales\Block\Adminhtml\Items\Column\Name" name="column_name" template="items/column/name.phtml" group="column"/>
                <block class="Magento\Framework\View\Element\Text\ListText" name="order_item_extra_info"/>
            </block>

as we see the big block of tag infos is order_tab_info but it render just the child like order_history or order_payment. ok our solution is like (inside your sales_order_view.xml) :

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="left">
           <referenceContainer name="payment_additional_info">
            <block class="Ibnab\OrderAd\Block\Adminhtml\Order\View\View" name="sales_order_view_ad" template="order/view/ad.phtml"/>
             </referenceContainer>
        </referenceContainer>
    </body>
</page>

our ad.phtml:

<p></p>
<h1>Our Adiitional Block </h1>

enter image description here

that is a solution or try of how inject custom container

2
  • @lbnab Hi, I read your answer. Unfortunately I can't get it to work. Is it possible to create a quick github repo for this. That would be awesome.
    – Yetispapa
    Commented Nov 7, 2016 at 14:37
  • True way. Very strange - in Magento 2.4.5 - block "Payment & Shipping Method" still old - not as container.
    – Alex
    Commented Jun 14, 2023 at 10:37
2

Here is the solution that works for me:

sales_order_view.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>      
       <referenceBlock name="order_info">
            <action method="setTemplate">
                <argument name="template" translate="true" xsi:type="string">MD_Demo::order/view/info.phtml</argument>
            </action>
        </referenceBlock>
    </body>
</page>

order/view/info.ptml

<?php $_order = $block->getOrder() ?>
<?php
$orderAdminDate = $block->formatDate(
    $block->getOrderAdminDate($_order->getCreatedAt()),
    \IntlDateFormatter::MEDIUM,
    true
);
$orderStoreDate = $block->formatDate(
    $_order->getCreatedAt(),
    \IntlDateFormatter::MEDIUM,
    true,
    $block->getTimezoneForStore($_order->getStore())
);
?>
<section class="admin__page-section order-view-account-information">
    <div class="admin__page-section-title">
        <span class="title"><?php /* @escapeNotVerified */ echo __('Order & Account Information') ?></span>
    </div>
    <div class="admin__page-section-content">
        <div class="admin__page-section-item order-information">
            <?php /* Order Information */?>
            <?php if ($_order->getEmailSent()):
                $_email = __('The order confirmation email was sent');
            else:
                $_email = __('The order confirmation email is not sent');
            endif; ?>
            <div class="admin__page-section-item-title">
                <span class="title">
                    <?php if ($block->getNoUseOrderLink()): ?>
                        <?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?> (<span><?php /* @escapeNotVerified */ echo $_email ?></span>)
                    <?php else: ?>
                        <a href="<?php /* @escapeNotVerified */ echo $block->getViewUrl($_order->getId()) ?>"><?php /* @escapeNotVerified */ echo __('Order # %1', $_order->getRealOrderId()) ?></a>
                        <span>(<?php /* @escapeNotVerified */ echo $_email ?>)</span>
                    <?php endif; ?>
                </span>
            </div>
            <div class="admin__page-section-item-content">
                <table class="admin__table-secondary order-information-table">
                <tr>
                    <th><?php /* @escapeNotVerified */ echo __('Order Date') ?></th>
                    <td><?php /* @escapeNotVerified */ echo $orderAdminDate ?></td>
                </tr>
                <?php if ($orderAdminDate != $orderStoreDate):?>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __(
                                'Order Date (%1)',
                                $block->getTimezoneForStore($_order->getStore())
                            ) ?></th>
                        <td><?php /* @escapeNotVerified */ echo $orderStoreDate ?></td>
                    </tr>
                <?php endif;?>
                <tr>
                    <th><?php /* @escapeNotVerified */ echo __('Order Status') ?></th>
                    <td><span id="order_status"><?php /* @escapeNotVerified */ echo $_order->getStatusLabel() ?></span></td>
                </tr>
                <?php echo $block->getChildHtml(); ?>
                <?php if ($block->isSingleStoreMode() == false):?>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('Purchased From') ?></th>
                        <td><?php /* @escapeNotVerified */ echo $block->getOrderStoreName() ?></td>
                    </tr>
                <?php endif; ?>
                <?php if ($_order->getRelationChildId()): ?>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('Link to the New Order') ?></th>
                        <td><a href="<?php /* @escapeNotVerified */ echo $block->getViewUrl($_order->getRelationChildId()) ?>">
                                <?php /* @escapeNotVerified */ echo $_order->getRelationChildRealId() ?>
                            </a></td>
                    </tr>
                <?php endif; ?>
                <?php if ($_order->getRelationParentId()): ?>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('Link to the Previous Order') ?></th>
                        <td><a href="<?php /* @escapeNotVerified */ echo $block->getViewUrl($_order->getRelationParentId()) ?>">
                                <?php /* @escapeNotVerified */ echo $_order->getRelationParentRealId() ?>
                            </a></td>
                    </tr>
                <?php endif; ?>
                <?php if ($_order->getRemoteIp() && $block->shouldDisplayCustomerIp()): ?>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('Placed from IP') ?></th>
                        <td><?php /* @escapeNotVerified */ echo $_order->getRemoteIp(); echo($_order->getXForwardedFor()) ? ' (' . $block->escapeHtml($_order->getXForwardedFor()) . ')' : ''; ?></td>
                    </tr>
                <?php endif; ?>
                <?php if ($_order->getGlobalCurrencyCode() != $_order->getBaseCurrencyCode()): ?>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('%1 / %2 rate:', $_order->getGlobalCurrencyCode(), $_order->getBaseCurrencyCode()) ?></th>
                        <td><?php /* @escapeNotVerified */ echo $_order->getBaseToGlobalRate() ?></td>
                    </tr>
                <?php endif; ?>
                <?php if ($_order->getBaseCurrencyCode() != $_order->getOrderCurrencyCode()): ?>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('%1 / %2 rate:', $_order->getOrderCurrencyCode(), $_order->getBaseCurrencyCode()) ?></th>
                        <th><?php /* @escapeNotVerified */ echo $_order->getBaseToOrderRate() ?></th>
                    </tr>
                <?php endif; ?>
            </table>
            </div>
        </div>
        <div class="admin__page-section-item order-account-information">
            <?php /* Account Information */?>
            <div class="admin__page-section-item-title">
                <span class="title"><?php /* @escapeNotVerified */ echo __('Account Information') ?></span>
                <div class="actions"><?php /* @escapeNotVerified */ echo $block->getAccountEditLink()?></div>
            </div>
            <div class="admin__page-section-item-content">
                <table class="admin__table-secondary order-account-information-table">
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('Customer Name') ?></th>
                        <td>
                            <?php if ($_customerUrl = $block->getCustomerViewUrl()) : ?>
                                <a href="<?php /* @escapeNotVerified */ echo $_customerUrl ?>" target="_blank">
                                    <span><?php echo $block->escapeHtml($_order->getCustomerName()) ?></span>
                                </a>
                            <?php else: ?>
                                <?php echo $block->escapeHtml($_order->getCustomerName()) ?>
                            <?php endif; ?>
                        </td>
                    </tr>
                    <tr>
                        <th><?php /* @escapeNotVerified */ echo __('Email') ?></th>
                        <td><a href="mailto:<?php echo $block->escapeHtml($_order->getCustomerEmail()) ?>"><?php echo $block->escapeHtml($_order->getCustomerEmail()) ?></a></td>
                    </tr>
                    <?php if ($_groupName = $block->getCustomerGroupName()) : ?>
                        <tr>
                            <th><?php /* @escapeNotVerified */ echo __('Customer Group') ?></th>
                            <td><?php /* @escapeNotVerified */ echo $_groupName ?></td>
                        </tr>
                    <?php endif; ?>
                    <?php foreach ($block->getCustomerAccountData() as $data):?>
                        <tr>
                            <th><?php /* @escapeNotVerified */ echo $data['label'] ?></th>
                            <td><?php /* @escapeNotVerified */ echo $data['value'] ?></td>
                        </tr>
                    <?php endforeach;?>
                </table>
            </div>
        </div>
    </div>
</section>
<section class="admin__page-section order-addresses">
    <div class="admin__page-section-title">
        <span class="title"><?php /* @escapeNotVerified */ echo __('Address Information') ?></span>
    </div>
    <div class="admin__page-section-content">
        <div class="admin__page-section-item order-billing-address">
            <?php /* Billing Address */?>
            <div class="admin__page-section-item-title">
                <span class="title"><?php /* @escapeNotVerified */ echo __('Billing Address') ?></span>
                <div class="actions"><?php /* @escapeNotVerified */ echo $block->getAddressEditLink($_order->getBillingAddress()); ?></div>
            </div>
            <address class="admin__page-section-item-content"><?php /* @escapeNotVerified */ echo $block->getFormattedAddress($_order->getBillingAddress()); ?></address>
        </div>
        <?php if (!$block->getOrder()->getIsVirtual()): ?>
            <div class="admin__page-section-item order-shipping-address">
                <?php /* Shipping Address */ ?>
                <div class="admin__page-section-item-title">
                    <span class="title"><?php /* @escapeNotVerified */ echo __('Shipping Address') ?></span>
                    <div class="actions"><?php /* @escapeNotVerified */ echo $block->getAddressEditLink($_order->getShippingAddress()); ?></div>
                </div>
                <address class="admin__page-section-item-content"><?php /* @escapeNotVerified */ echo $block->getFormattedAddress($_order->getShippingAddress()); ?></address>
            </div>
        <?php endif; ?>
    </div>
</section>
<section>
                    <H1>HERE IS IT MY BLOCK<H1>

</section>
1

Follow this link to get the solution.Even i got the same proplem.Magento 2 doesn't directly render the custom phtml data in order view information page.First override the sales_order_view.xml and info.phtml or any respective core phtml.which core phtml you have to choose that depends on at which core block you want to add new custom block.So for example if you want to add new block at Order & Account Information then override the info.phtml. we have to render the the custom phtml data using getChildHtml('layout name'); in info.phtml

Add custom block to order view information in admin Magento 2

0

In case that you are trying to put your content in the main container, I recommend you to try this in the ** sales_order_view.xml ** file:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>      
        <referenceContainer name="content">
            <block class="Tcc\Shipping\Block\Adminhtml\Order\View\Custom" name="sales_order_view_custom" template="order/view/custom.phtml"/>
        </referenceContainer>
    </body>
</page>
1
  • how to load that content after the Shipping & Handling Information? Commented Oct 26, 2018 at 7:32
0

After a lot of trial and error I found a safer solution than many of these answers

<?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>
        <referenceContainer name="left">
            <referenceBlock name="sales_order_tabs">
                <referenceBlock name="order_tab_info">
                    <referenceBlock name="order_info">
                        <container name="extra_customer_info">
                            <block class="Xigen\Booked\Block\Order\Booked" name="xigen_booked_order_booked" template="Xigen_Booked::order/view/info.phtml"/>
                        </container>
                    </referenceBlock>
                </referenceBlock>
            </referenceBlock>
        </referenceContainer>
    </body>
</page>

I've got a custom block file and template file

But no need to rewrite all the template logic like the answer shown here

https://magento.stackexchange.com/a/180620/70343

view/adminhtml/templates/order/view/info.phtml
<?php use Xigen\Booked\Helper\Booked; ?>
<?php if ($booked = $block->getBooked()): ?>
<table class="admin__table-secondary order-account-information-table">
    <tbody>
        <tr>
            <th style="background-color: #fff;"><?= $block->escapeHtml(__('Order Booked')) ?></th>
            <td style="background-color: #fff;">
                <?php if ($booked == Booked::BOOKED): ?>
                    <?= $block->escapeHtml(__("Yes")); ?>
                <?php endif;?>
                <?php if ($booked == Booked::NOT_BOOKED): ?>
                    <?= $block->escapeHtml(__("No")); ?>
                <?php endif;?>
            </td>
        </tr>
    </tbody>
</table>
<?php endif; ?>
1
0

I have used ViewModel instead of block class - Magento 2.3 onwards

ViewModel class

    <?php
namespace BA\BasysOrders\ViewModel;

use Psr\Log\LoggerInterface;
use Magento\Framework\App\Request\Http;

class BasysInfo implements \Magento\Framework\View\Element\Block\ArgumentInterface
{
    protected $logger;
    protected $request;
    protected $order;

    public function __construct(
        LoggerInterface $logger,
        Http $request,
        \Magento\Sales\Api\OrderRepositoryInterface $order
    ) {
        $this->logger = $logger;
        $this->request = $request;
        $this->order = $order;
    }
    public function getOrderId()
    {
        $this->logger->info('order id '.$this->request->getParam('order_id'));
        $order = $this->order->get(60);
        $this->logger->info('basys order id '.$order->getData('basys_order_id'));
        return $order->getData('basys_order_id');
    }
}

Phtml template

<?php
    $viewModel = $block->getViewModel();
?>
<h3>Additional Information</h3>
<table>
    <tr>
        <td>Basys Order Id : <?= $block->escapeHtml($viewModel->getOrderId()); ?></td>
    </tr>
</table>

sales_order_view.xml

<referenceBlock name="order_additional_info">
            <container name="basys_info" htmlTag="div" htmlClass="basys_info">
                <block name="basysinfo.viewmodel" template="BA_BasysOrders::order/view/basysinfo.phtml">
                    <arguments>
                        <argument name="view_model" xsi:type="object">BA\BasysOrders\ViewModel\BasysInfo</argument>
                    </arguments>
                </block>
            </container>
        </referenceBlock>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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