Magento 2 : Show multiple store view in admin custom module grid.

Recently, I have created custom module without UI component. I want to add store view field on that. I have added in form easily but put me in trouble little bit during grid. To show multiple store in admin custom module grid, I have used renderer and following changes in grid.php file

 Custom\Slider\Block\Adminhtml\Slide\Grid.php

$this->addColumn(
    'store_ids',
    [
        'header' => __('Store Views'),
        'index' => 'store_ids',                        
        'type' => 'store',
        'store_all' => true,
        'store_view' => true,
        'renderer'=>  'Custom\Slider\Block\Adminhtml\Slide\Edit\Tab\Renderer\Store',
        'filter_condition_callback' => [$this, '_filterStoreCondition']
    ]
);

Custom\Slider\Block\Adminhtml\Slide\Edit\Tab\Renderer\Store.php

', $scopes) . __(' [deleted]');
            return $out;
        }

        if (empty($origStores) && !$skipEmptyStoresLabel) {
            return '';
        }
        if (!is_array($origStores)) {
            $origStores = [$origStores];
        }

        if (empty($origStores)) {
            return '';
        } elseif (in_array(0, $origStores) && count($origStores) == 1 && !$skipAllStoresLabel) {
            return __('All Store Views');
        }

        $data = $this->_getStoreModel()->getStoresStructure(false, $origStores);

        foreach ($data as $website) {
            $out .= $website['label'] . '
';
            foreach ($website['children'] as $group) {
                $out .= str_repeat(' ', 3) . $group['label'] . '
';
                foreach ($group['children'] as $store) {
                    $out .= str_repeat(' ', 6) . $store['label'] . '
';
                }
            }
        }

        return $out;
    }

    /**
     * Render row store views for export
     *
     * @param \Magento\Framework\DataObject $row
     * @return \Magento\Framework\Phrase|string
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     */
    public function renderExport(\Magento\Framework\DataObject $row)
    {
        $out = '';
        $skipAllStoresLabel = $this->_getShowAllStoresLabelFlag();
        // $origStores = $row->getData($this->getColumn()->getIndex());
        $origStores = explode(',',$row->getData($this->getColumn()->getIndex()));

        if ($origStores === null && $row->getStoreName()) {
            $scopes = [];
            foreach (explode("\n", $row->getStoreName()) as $k => $label) {
                $scopes[] = str_repeat(' ', $k * 3) . $label;
            }
            $out .= implode("\r\n", $scopes) . __(' [deleted]');
            return $out;
        }

        if (!is_array($origStores)) {
            $origStores = [$origStores];
        }

        if (in_array(0, $origStores) && !$skipAllStoresLabel) {
            return __('All Store Views');
        }

        $data = $this->_getStoreModel()->getStoresStructure(false, $origStores);

        foreach ($data as $website) {
            $out .= $website['label'] . "\r\n";
            foreach ($website['children'] as $group) {
                $out .= str_repeat(' ', 3) . $group['label'] . "\r\n";
                foreach ($group['children'] as $store) {
                    $out .= str_repeat(' ', 6) . $store['label'] . "\r\n";
                }
            }
        }

        return $out;
    }
}

Output : store view

Cheers !!!

Add external url in navigation menu in magento 2

If you want to add your external linklike static page link or some custom module link in your category navigation menu, you can do it by your self. You have do custom code in custom module. Just follow the instructions and create module files.

  1. app/code/A2bizz/Navigation/registration.php
<?php 
\Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'A2bizz_Navigation',
        __DIR__
        );

 

2.  app/code/A2bizz/Navigation/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="A2bizz_Navigation"  setup_version="0.0.1">
        <sequence>
            <module name="Magento_Theme"/>
        </sequence>
    </module>
</config>

 

3. Add app\code\A2bizz\Navigation\etc\frontend\di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Theme\Block\Html\Topmenu">
    <plugin name="add_menu_item_plugin" type="A2bizz\Navigation\Plugin\Topmenu" sortOrder="10" disabled="false"/>
</type>
</config>

It is saying that plugin which you have defined in A2bizz\Navigation\Plugin\Topmenu will use when Magento\Theme\Block\Html\Topmenu block is used.

4.  app/code/A2bizz/Navigation/Plugin/Topmenu.php

<?php

namespace A2bizz\Navigation\Plugin;

class Topmenu
{
    public function afterGetHtml(\Magento\Theme\Block\Html\Topmenu $topmenu, $html)
    {
        $html .= "<li class=\"level0 nav-4 level-top parent ui-menu-item\">";
        $html .= "<a href=\"" . "EXTERNAL_URL" . "\" class=\"level-top ui-corner-all\" aria-haspopup=\"true\" tabindex=\"-1\" role=\"menuitem\"><span class=\"ui-menu-icon ui-icon ui-icon-carat-1-e\"></span><span>" . __("EXTERNAL_URL_TITLE") . "</span></a>";
        $html .= "<ul class=\"level0 submenu ui-menu ui-widget ui-widget-content ui-corner-all\" role=\"menu\" aria-expanded=\"false\" style=\"display: none; top: 47px; left: -0.4375px;\" aria-hidden=\"true\">";

        $html .= "<li class=\"level1 nav-5-1 first ui-menu-item\" role=\"presentation\">";
        $html .= "<a href=\"" . "EXTERNAL_URL" . "\" class=\"ui-corner-all\" tabindex=\"-1\" role=\"menuitem\"><span>" . __("EXTERNAL_URL_TITLE") . "</span></a>";
        $html .= "</li>";

        $html .= "<li class=\"level1 nav-5-1 first ui-menu-item\" role=\"presentation\">";
        $html .= "<a href=\"" . "EXTERNAL_URL" . "\" class=\"ui-corner-all\" tabindex=\"-1\" role=\"menuitem\"><span>" . __("EXTERNAL_URL_TITLE") . "</span></a>";
        $html .= "</li>";

        $html .= "<li class=\"level1 nav-5-1 first ui-menu-item\" role=\"presentation\">";
        $html .= "<a href=\"" . "EXTERNAL_URL" . "\" class=\"ui-corner-all\" tabindex=\"-1\" role=\"menuitem\"><span>" . __("EXTERNAL_URL_TITLE") . "</span></a>";
        $html .= "</li>";

        $html .= "</ul>";
        $html .= "</li>";

        return $html;
    }
}

After these changes, you have to do setup upgrade by terminal. Open terminal, go to the root directory of installed mangento and run following command.

php bin/magento setup:upgrade

ENJOY !!!

Magento 2 : Create custom logging

 

Magento 2 uses monolog library to log messages. You can check this library in following  path location in magento 2.

<magento_root_folder>/vendor/monolog/

Log file will be created inside var/log folder

If you want to use log in your custom module, you need to add instance of  monolog class in your custom file class. You need to pass the instance in the constructor of your custom class.

Go to app/code/yourCompany/yourModule/Block/custom.php

add following protected variable  in custom file class.

/**
* @var \Psr\Log\LoggerInterface
*/
protected $_logger;

add following parameter in your custom class  __construct()

\Psr\Log\LoggerInterface $logger

Now, we need to create an object

$this->_logger = $logger;
$this->_logger->addDebug('some text or variable');

Finally, constructor function looks like following

public function __construct(
        \Magento\Framework\View\Element\Context $context,
        \Magento\Cms\Model\Page $page,
        \Magento\Cms\Model\Template\FilterProvider $filterProvider,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Cms\Model\PageFactory $pageFactory,
        \Magento\Framework\View\Page\Config $pageConfig,
        \Psr\Log\LoggerInterface $logger,
        array $data = []
    ) {
        parent::__construct($context, $data);
        // used singleton (instead factory) because there exist dependencies on \Magento\Cms\Helper\Page
        $this->_page = $page;
        $this->_filterProvider = $filterProvider;
        $this->_storeManager = $storeManager;
        $this->_pageFactory = $pageFactory;
        $this->pageConfig = $pageConfig;
        $this->_logger = $logger;
        $this->_logger->addDebug('some text or variable');
    }

Here is the use of some predefined examples :

$this->_logger->addDebug($message); // log location: var/log/system.log
$this->_logger->addInfo($message); // log location: var/log/exception.log
$this->_logger->addNotice($message); // log location: var/log/exception.log
$this->_logger->addError($message); // log location: var/log/exception.log
$this->_logger->critical($e); // log location: var/log/exception.log
You can also write to the logs using the zend library
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/test.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('Your text message');

Magento 2 : Create customer group programmatically

Here is the way to add customer groups programmatically in Magento 2, use $group->save() on the model returned by the GroupFactory:

namespace A2bizz\MyCustomModule\Setup;
 
use Magento\Framework\Module\Setup\Migration;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Customer\Model\GroupFactory;
 
class InstallData implements InstallDataInterface
{
    protected $groupFactory;
 
    /**
     * Customer group factory
     */
    public function __construct(GroupFactory $groupFactory) {
        $this->groupFactory = $groupFactory;
    }
 
    public function install(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        $setup->startSetup();
 
        // Create the new group
        /** @var \Magento\Customer\Model\Group $group */
        $group = $this->groupFactory->create();
        $group
            ->setCode('New Customer Group');
            ->setTaxClassId(3) 
            ->save();
 
        $setup->endSetup();
    }
}

Magento 2: Set developer mode

Magneto supports a developer mode.

This is intended for internal development on a system already secured. During customizing the Magento Software, you should run magento software in developer mode.  It shows exceptions on screen instead of showing a generic error message like “There has been an error processing your request“.

In Developer mode :

  • Static view files are not cached, they are written to the Magento pub/static directory every time they’re called
  • Display uncaught exceptions in the screen.
  • System logging in var/report is verbose
  • An exception is thrown in the error handler, rather than being logged

Here is following way to setup developer mode :

1.  Add below line in  index.php

$_SERVER['MAGE_MODE'] = 'developer';

2. Run following command in terminal/command line :

bin/magento deploy:mode:set mode=developer

 

Magento2 create custom theme

Today, We going to learn, how to create custom theme in magento2 , or how we can start to add our own customized theme, to do so, please follow the below steps –

1. Create the path app/design/frontend/a2bizz/custom, where a2bizz and custom are your own package and theme names respectively, whatever you like to give name, give it.

2. Now create a file theme.xml inside the above path, and write below given code –

<theme xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation = "../../../../../lib/internal/Magento/Framework/Config/etc/theme.xsd">
 <title>A2bizz Custom theme</title>
 <parent>Magento/blank</parent> <!--the parent theme, in case your theme inherits from an existing theme -->
 <media>
   <preview_image>media/preview.jpg</preview_image>
  </media>
</theme>

Now, register your theme and create a file registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::THEME,
    'frontend/a2bizz/custom',
    __DIR__
);

Now, the registration of a custom theme is being completed and it has been added to the list of themes, go to the admin section and Select your custom theme from admin >> store >> Configuration >> General >> Design. to change the theme.

Magento2 call cms static block

 Buy cheap and genuine Windows 7 product key  |
 Windows 7 Product Key for Windows 32bit/64bit Updated 2016y  |
 Windows 7 Ultimate ISO download  |
 Windows 7 Product Key Generator 32 bit and 64 bit Full  |
 Legit Windows 7 Product Key Online Store, PayPal Support  |
 Windows 7 Ultimate with Service Pack 1 Product Key,Windows 7 Key Sale  |
 Windows 7 Key  |
 Get Free Windows 7 Product Key  |
windows-10-education-key
windows-10-enterprise-key
office-2010-key
windows-7-key-sale
windows-10-home-key
windows-10-activation-key
windows-10-pro-key
office-2016-key
windows-10-key
office-2013-key
windows-10-iso
windows-7-key
windows-10-product-key

If you want to call cms block in .phtml template file then add below code to your phtml file –

<?php echo $block->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId('a2bizz_block_identifier')->toHtml();?>

If you want to call cms block in .xml file, then add below code to the layout file –

<referenceContainer name="content">
  <block class="Magento\Cms\Block\Block" name="a2bizz_block_identifier">
   <arguments>
     <argument name="a2bizz_block_id" xsi:type="string">a2bizz_block_identifier</argument>
   </arguments>
 </block>
</referenceContainer>

If you want to call cms block in CMS Page

{{block class="Magento\\Cms\\Block\\Block" block_id="a2bizz_block_identifier"}}

Magento2: create custom module

Today we will learn to create custom module in magento2-

For installation and initial learning please visit our previous blogs of magento2.

The overall development we are doing on Ubuntu 14.4, local environment the base directory structure of my local is –
/var/www/html/magento2/app/code/A2bizz/Blog

You can download full code from GIT below given URL –
https://github.com/bloga2bizz/Magento2-Sample-Frontend-Module

customModule

Step 1.Initialization of your custom module –

First of all we will have to initialize our custom module to the list of modules with magento configuration, for which we will have to first create a /var/www/html/magento2/app/code/A2bizz/Blog/registration.php file and write below code –

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'A2bizz_Blog',
__DIR__
);

?>

if you hit your magento2 URL i.e. http://localhost/magento2/, now you will get below issue –

Cannot read contents from file "/var/www/html/magento2/app/code/A2bizz/Blog/etc/module.xml"

Now create module.xml on file /var/www/html/magento2/app/code/A2bizz/Blog/etc/module.xml and write below code –

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="A2bizz_Blog" setup_version="2.0.0" />
</config>

Now we have initialised our custom module, To check that please check /var/www/html/magento2/app/etc/config.php where your created module will be listed down, if not then upgrade custom module.

Step 2. creating controller & routing –

Now Further create controller file /var/www/html/magento2/app/code/A2bizz/Blog/Controller/Index/Index.php

<?php

namespace A2bizz\Blog\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action
{    
	protected $resultPageFactory;

	public function __construct(
		\Magento\Framework\App\Action\Context $context,
		\Magento\Framework\View\Result\PageFactory $resultPageFactory
	)
	{
		$this->resultPageFactory = $resultPageFactory;
		parent::__construct($context);
	}
    
    public function execute()
    {
        return $this->resultPageFactory->create();
    }

}

and a routes.xml file on path /var/www/html/magento2/app/code/A2bizz/Blog/etc/frontend/routes.xml,which will provide the path execution to your custom module –

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="blog" frontName="blog">
            <module name="A2bizz_Blog" />
        </route>
    </router>
</config>

here, in this xml we initializing the calling path for our custom module. In this way we have successfully hit out the controller for our custom module. Here in our example hit – http://127.0.0.1/magento2/blog

if the hitting above URL is showing blank white page, it means controller is hitted in a proper manner and now asking for the page layout.

Step 3. designing layout (view) for our custom module –

Now Further create layout files for your custom module /var/www/html/magento2/app/code/A2bizz/Blog/view/frontend/layout/blog_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="A2bizz\Blog\Block\Blog" name="blog" template="A2bizz_Blog::blog.phtml" />
        </referenceContainer>
    </body>
</page>

and add /var/www/html/magento2/app/code/A2bizz/Blog/view/frontend/templates/blog.phtml

<?php
echo "Blog Template";
?>

Now hit your custom module URL again, will show you below error
Object DOMDocument should be created.

it means it is unable to find corresponding Block method for its layout.

Now create your Block method, in /var/www/html/magento2/app/code/A2bizz/Blog/Block/Blog.php

<?php
namespace A2bizz\Blog\Block;

class Blog extends \Magento\Framework\View\Element\Template
{
	public function _prepareLayout()
	{
	    return parent::_prepareLayout();
	}
}
?>

Now, Executing your URL http://localhost/magento2/blog, will show you complete module functionality.

Magento 2 Overriding Controller

This post walks through the process to override a controller in Magento 2.

There are a few steps to override a Magento 2 controller.

Step 1. Building a Magento 2 extension structure

Building directories as given following:

magento2 --- app --- code
                       |--- A2bizz --- Sample
                       | --- Controller
                       | --- etc
                              | --- module.xml
                              | --- di.xml

Creating module.xml to define a Magento2 extension:

<?xml version="1.0"?>
<!--
/**
 * Created by blog.a2bizz@gmail.com
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="A2bizz_Sample" setup_version="0.0.1"/>
</config>

Step 2. Setting preference in di.xml

Creating di.xml to refer the overriding class:

<?xml version="1.0"?>
<!--
/**
 * Created by blog.a2bizz@gmail.com
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<preference for="Magento\Cms\Controller\Index\Index" type="A2bizz\Sample\Controller\Index\Index" /> 
</config>

A2bizz\Sample\Controller\Index\Index will be used to override Magento\Cms\Controller\Index\Index, which is the homepage in original Magento 2.

Step 3. Defining an overriding controller class

Under magento2/app/code/A2bizz/Sample/Controller, defining Index.php as following.

<?php
/**
 * Created by blog.a2bizz@gmail.com
 */
namespace A2bizz\Sample\Controller\Index;
class Index extends \Magento\Cms\Controller\Index\Index
{
    public function execute($coreRoute = null)
    {
        $this->messageManager->addSuccess('Message from new controller.');
        return parent::execute($coreRoute);
    }
} 

Index.php redefines function execute() to override the function in \Magento\Cms\Controller\Index\Index. The new execute() adds a message to homepage, but it may also implements a complex logic.

Magento2: Overriding Block

This post go through the process to extend a block in Magento2.

There are a few steps to override a Magento2 block as given below –

Step 1. Building a Magento 2 extension structure

Building directories as following:

magento2 --- app --- code
                       |--- A2bizz --- Sample
                                             | --- Block
                                             | --- etc
                                                    | --- module.xml
                                                    | --- di.xml

Creating module.xml to define a Magento2 extension:

<?xml version="1.0"?>
<!--
/**
 * Created by blog.a2bizz@gmail.com
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="A2bizz_Sample" setup_version="0.0.1"/>
</config>

Step 2. Setting preference in di.xml

Creating di.xml to refer the overriding block class:

<?xml version="1.0"?> 
<!-- /** * Created by blog.a2bizz@gmail.com */ --> 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> 
<preference for="Magento\Theme\Block\Html\Title" type="A2bizz\Sample\Block\HelloTitle" /> 
</config> 

A2bizz\Sample\Block\HelloTitle will be used to override Magento\Theme\Block\Html\Title.

Step 3. Defining an overriding class

Under magento2/app/code/A2bizz/Sample/Block, defining HelloTitle.php as following.

<?php
/**
 * Created by blog.a2bizz@gmail.com
 */
namespace A2bizz\Sample\Block;
use Magento\Framework\View\Element\Template;
class HelloTitle extends \Magento\Theme\Block\Html\Title
{
    public function getPageTitle()
    {
        return 'A2bizz Custom';
    }
    protected function _toHtml()
    {
        $this->setModuleName($this->extractModuleName('Magento\Theme\Block\Html\Title'));
        return parent::_toHtml();
    }
}

HelloTitle.php redefines function getPageTitle() to override the function in \Magento\Theme\Block\Html\Title. The new getPageTitle() just return a text string, but it may also implements a complex logic.

HelloTitle.php also redefines function _toHtml(). Although HelloTitle overrides \Magento\Theme\Block\Html\Title, the template file of \Magento\Theme\Block\Html\Title is still supposed to be used. And the real path of a template file is determined by both the module name of a block and the template attribute of the block. Therefore, the module name of HelloTitle is still Magento_Theme, rather than A2bizz_Sample.

This line

$this->setModuleName($this->extractModuleName('Magento\Theme\Block\Html\Title'));

sets the correct nominal module name. This module name is necessary to render with the template originally defined for Magento\Theme\Block\Html\Title.