Magento 2 eBook - Development Cookbook EBook
With a big catalog of 234+ extensions for your online store
CREDITS
- Magento expert: Brian Tran
- Editor: Tracy Vu.
- Assistant Editor: Linda Thompson.
- Design: Sam Thomas.
- Special thanks to: LiLy White, Brian Tran.
- Also thanks to Mageplaza team who supported a lot in the release of this special Module Development ebook for Magento 2.
Copyright © 2016 by Mageplaza.
Texts by kind permission of the authors.
Pictures by kind permission of the holders of the picture rights.
All rights reserved.
Magento 2 Module development or Magento 2 Hello World module trends is increase rapidly while Magento release official version. That why we - Mageplaza - are wring about a topic that introduces how to create a simple Hello World module in Magento 2.
As you know, the module is a directory that contains blocks, controllers, models, helper
, etc - that are related to a specific business feature. In Magento 2 modules will be live in app/code
directory of a Magento installation, with this format: app/code/<Vendor>/<ModuleName>
. Now we will follow this steps to create a simple module which work on Magento 2 and display Hello World
.
Magento 2 Hello World module by Mageplaza.com
- Step 1: Create a directory for the module like above format.
- Step 2: Declare module by using configuration file module.xml
- Step 3: Register module by registration.php
- Step 4: Enable the module
- Step 5: Create a Routers for the module.
- Step 6: Create controller and action.
Step 1. Create a directory for the module like above format.
In this module, we will use Mageplaza
for Vendor name and HelloWorld
for ModuleName. So we need to make this folder:
app/code/Mageplaza/HelloWorld
Step 2. Declare module by using configuration file module.xml
Magento 2 looks for configuration information for each module in that module’s etc directory. We need to create folder etc and add module.xml:
app/code/Mageplaza/HelloWorld/etc/module.xml
And the content for this file:
<?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="Mageplaza_HelloWorld" setup_version="1.0.0" />
</config>
In this file, we register a module with name Mageplaza_HelloWorld
and the version is 1.0.0
.
Step 3. Register module by registration.php
All Magento 2 module must be registered in the Magento system through the magento ComponentRegistrar class. This file will be placed in module root directory. In this step, we need to create this file:
app/code/Mageplaza/HelloWorld/registration.php
And it’s content for our module is:
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Mageplaza_HelloWorld',
__DIR__
);
Step 4. Enable the module
By finish above step, you have created an empty module. Now we will enable it in Magento environment. Before enable the module, we must check to make sure Magento has recognize our module or not by enter the following at the command line:
php bin/magento module:status
If you follow above step, you will see this in the result:
List of disabled modules:
Mageplaza_HelloWorld
This means the module has recognized by the system but it is still disabled. Run this command to enable it:
php bin/magento module:enable Mageplaza_HelloWorld
The module has enabled successfully if you saw this result:
The following modules has been enabled:
- Mageplaza_HelloWorld
This’s the first time you enable this module so Magento require to check and upgrade module database. We need to run this comment:
php bin/magento setup:upgrade
Now you can check under Stores -> Configuration -> Advanced -> Advanced
that the module is present.
Step 5. Create a Routers for the module.
In the Magento system, a request URL has the following format:
http://example.com/<router_name>/<controller_name>/<action_name>
The Router is used to assign a URL to a corresponding controller and action. In this module, we need to create a route for frontend area. So we need to add this file:
app/code/Mageplaza/HelloWorld/etc/frontend/routes.xml
And content for this file:
<?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="mageplaza" frontName="helloworld">
<module name="Mageplaza_HelloWorld" />
</route>
</router>
</config>
After define the route, the URL path to our module will be: http://example.com/helloworld/*
Step 6. Create controller and action.
In this step, we will create controller and action to display Hello World
.
Now we will choose the url for this action. Let assume that the url will be:
http://example.com/helloworld/index/display
So the file we need to create is:
app/code/Mageplaza/HelloWorld/Controller/Index/Display.php
And we will put this content:
<?php
namespace Mageplaza\HelloWorld\Controller\Index;
class Display extends \Magento\Framework\App\Action\Action
{
public function __construct(
\Magento\Framework\App\Action\Context $context)
{
return parent::__construct($context);
}
public function execute()
{
echo 'Hello World';
exit;
}
}
If you have followed all above steps, you will see Hello World
when open the url http://example.com/helloworld/index/display
In this topic Magento 2 Create: Block, Layouts, Templates we will learn about View in Magento 2 including Block, Layouts and Templates. In previous topic, we discussed about CRUD Models . As you know, a View will be use to output representation of the page. In Magento 2, View is built by three path: block, layout and template. We will find how it work by building the simple module Hello World using View path.
To create view in Magento 2
- Step 1: Call view in controller
- Step 2: Declare layout file
- Step 3: Create block
- Step 4. Create template file
Step 1: Call view in controller
In the previous Hello World Module topic, we have build a simple module and show the Hello World
message on the screen directly by controller. Now we will edit it to call view to render page.
#file: app/code/Mageplaza/HelloWorld/Controller/Index/Display.php
<?php
namespace Mageplaza\HelloWorld\Controller\Index;
class Display extends \Magento\Framework\App\Action\Action
{
protected $_pageFactory;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $pageFactory)
{
$this->_pageFactory = $pageFactory;
return parent::__construct($context);
}
public function execute()
{
return $this->_pageFactory->create();
}
}
We have to declare the PageFactory and create it in execute method to render view.
Step 2: Declare layout file
The Layout is the major path of view layer in Magento 2 module. The layout file is a XML file which will define the page structure and will be locate in {module_root}/view/{area}/layout/
folder. The Area path can be frontend or adminhtml which define where the layout will be applied.
There is a special layout file name default.xml
which will be applied for all the page in it’s area. Otherwhile, the layout file will have name as format: {router_id}_{controller_name}_{action_name}.xml
.
You can understand the layout in detail in this Magento topic , and the instruction of a layout structure.
When rendering page, Magento will check the layout file to find the handle for the page and then load Block and Template. We will create a layout handle file for this module:
#file: app/code/Mageplaza/HelloWorld/view/frontend/layout/helloworld_index_display.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">
<referenceContainer name="content">
<block class="Mageplaza\HelloWorld\Block\Display" name="helloworld_display" template="Mageplaza_HelloWorld::sayhello.phtml" />
</referenceContainer>
</page>
In this file, we define the block and template for this page:
Block class: Mageplaza\HelloWorld\Block\Display
Template file: Mageplaza_HelloWorld::sayhello.phtml
Step 3: Create block
The Block file should contain all the view logic required, it should not contain any kind of html or css. Block file are supposed to have all application view logic.
Create a file:
app/code/Mageplaza/HelloWorld/Block/Display.php
The Block for this module:
<?php
namespace Mageplaza\HelloWorld\Block;
class Display extends \Magento\Framework\View\Element\Template
{
public function __construct(\Magento\Framework\View\Element\Template\Context $context)
{
parent::__construct($context);
}
public function sayHello()
{
return __('Hello World');
}
}
Every block in Magento 2 must extend from Magento\Framework\View\Element\Template
. In this block we will define a method sayHello() to show the word “Hello World”. We will use it in template file.
Step 4. Create template file
Create a template file call sayhello.phtml
app/code/Mageplaza/HelloWorld/view/frontend/templates/sayhello.phtml
Insert the following code:
<?php
echo $block->sayHello();
In the layout file, we define the template by Mageplaza_HelloWorld::sayhello.phtml
. It mean that Magento will find the file name sayhello.phtml in templates folder of module Mageplaza_HelloWorld. The template folder of the module is app/code/{vendor_name}/{module_name}/view/frontend/templates/
.
In the template file, we can use the variable $block for the block object. As you see, we call the method sayHello()
in Block.
It’s done, please access to this page again (http://example.com/helloworld/index/display) and see the result.
Controller specially is one of the important thing in Magento 2 module development, and PHP MVC Framework in general. It functionarity is that received request, process and render page.
In Magento 2 Controller has one or more files in Controller folder of module, it includes actions of class which contain execute()
method. There are 2 different controllers, they are frontend controller and backend controller. They are generally similar of workflow, but admin controller is a little different. There is a checking permission method in admin controller. Let’s take an example:
protected function _isAllowed()
{
return $this->_authorization->isAllowed('Magento_AdminNotification::show_list');
}
It will check the current user has right to access this action or not.
How controller work?
It receive an request from end-user (browser or comamnd line), for example:
http://example.com/route_name/controller/action
route_name
is a unique name which is set in routes.xml.controller
is the folder inside Controller folder.action
is a class with execute method to process request.
One of the important in Magento system is frontController (Magento\Framework\App\FrontController
), it alway receive request then route controller, action by route_name
Let take an example of routing an request:
foreach ($this->_routerList as $router) {
try {
$actionInstance = $router->match($request);
…
}
If there is an action of controller class found, execute()
method will be run.
How to create a controller?
To create a controller, we need to create a folder inside Controller
folder of module and declare an action class inside it. For example, we create a Test controller
and a Hello
action for module Mageplaza_HelloWorld
:
app/code/Mageplaza/HelloWorld/Controller/Test/SayHello.php
And content of this file should be:
namespace Mageplaza\HelloWorld\Controller\Test;
class SayHello extends \Magento\Framework\App\Action\Action
{
public function execute()
{
echo 'Hello World! Welcome to Mageplaza.com';
exit;
}
}
As you see, all controller must extend from \Magento\Framework\App\Action\Action
class which has dispatch method which will call execute method in action class. In this execute()
method, we will write all of our controller logic and will return response for the request.
Forward and redirect in action.
\Magento\Framework\App\Action\Action
class provide us 2 important methods: _forward
and _redirect
.
Forward method
_forward()
protected function will edit the request to transfer it to another controller/action
class. This will not change the request url. For example, we have 2 actions Forward and Hello World like this:
namespace Mageplaza\HelloWorld\Controller\Test;
class Forward extends \Magento\Framework\App\Action\Action
{
public function execute()
{
$this->_forward('hello');
}
}
If you make a request to http://example.com/route_name/test/forward
, here are result will be displied on the screen.
Hello World! Welcome to Mageplaza.com
You can also change the controller, module and set param for the request when forward. Please check the _forward()
function for more information:
protected function _forward($action, $controller = null, $module = null, array $params = null)
{
$request = $this->getRequest();
$request->initForward();
if (isset($params)) {
$request->setParams($params);
}
if (isset($controller)) {
$request->setControllerName($controller);
// Module should only be reset if controller has been specified
if (isset($module)) {
$request->setModuleName($module);
}
}
$request->setActionName($action);
$request->setDispatched(false);
}
Redirect method
This method will transfer to another controller/action
class and also change the response header and the request url. With above example, if we replace _forward()
method by this _redirect()
method:
$this->_redirect('*/*/hello');
Then after access from the url http://example.com/route_name/test/forward
, the url will be change to http://example.com/route_name/test/hello
and show the message Hello World! Welcome to Mageplaza.com
on the screen.
How to rewrite controller in Magento 2
To rewrite controller, you can do it by using preference. It mean that you need to put a rule in your router config using before attribute.
Open Mageplaza/HelloWorld/etc/di.xml
insert the following block of code inside <config>
tag rewrite controller in Magento 2
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<router id="standard">
<route id="mageplaza" frontName="hello">
<module name="Mageplaza_HelloWorld" before="Magento_Customer" />
</route>
</router>
</config>
This will completely change controller/action
of module Magento_Customer
with your controller code, so you should extend rewrite controller and make a change on the function which you want. Also, the controller and action in your module must have same name with rewrite controller/action
.
For example, if you want to rewrite controller: Magento\Customer\Controller\Account\Create.php
You have to register a router like above and create a controller:
NameSpace\ModuleName\Controller\Account\Create.php
Content of Create.php file:
namespace Mageplaza\HelloWorld\Controller\Account;
use Magento\Customer\Model\Registration;
use Magento\Customer\Model\Session;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\App\Action\Context;
class Create extends \Magento\Customer\Controller\AbstractAccount
{
/** @var Registration */
protected $registration;
/**
* @var Session
*/
protected $session;
/**
* @var PageFactory
*/
protected $resultPageFactory;
/**
* @param Context $context
* @param Session $customerSession
* @param PageFactory $resultPageFactory
* @param Registration $registration
*/
public function __construct(
Context $context,
Session $customerSession,
PageFactory $resultPageFactory,
Registration $registration
) {
$this->session = $customerSession;
$this->resultPageFactory = $resultPageFactory;
$this->registration = $registration;
parent::__construct($context);
}
/**
* Customer register form page
*
* @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page
*/
public function execute()
{
if ($this->session->isLoggedIn() || !$this->registration->isAllowed()) {
/** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
$resultRedirect->setPath('*/*');
return $resultRedirect;
}
/** @var \Magento\Framework\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
return $resultPage;
}
}
CRUD Models in Magento 2 can manage data in database easily, you don’t need to write many line of code to create a CRUD. CRUD is stand for Create, Read, Update and Delete. We will learn about some main contents: How to setup Database, Model, Resource Model and Resource Magento 2 Get Collection and do database related operations. In previous topic, we discussed about Creating Hello World Module
Before learning this topic, let’s decide how the table which we work with will look. I will create a table mageplaza_topic
and take the following columns:
topic_id
- the topic unique identifiertitle
- the title of the topiccontent
- the content of the topiccreation_time
- the date created
To create Model in Magento 2
- Step 1: Setup Script
- Step 2: Model
- Step 3: Resource Model
- Step 4: Resource Model Collection
- Step 5: Factory Object
Step 1: Setup Script
Firstly, we will create database table for our CRUD models. To do this we need to insert the setup file:
app/code/Mageplaza/HelloWorld/Setup/InstallSchema.php
This file will execute only one time when install the module. Let put this content for this file to create above table:
namespace Mageplaza\HelloWorld\Setup;
class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface
{
public function install(
\Magento\Framework\Setup\SchemaSetupInterface $setup,
\Magento\Framework\Setup\ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
$table = $installer->getConnection()->newTable(
$installer->getTable('mageplaza_topic')
)->addColumn(
'topic_id',
\Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
null,
['identity' => true, 'nullable' => false, 'primary' => true, 'unsigned' => true],
'Topic ID'
)->addColumn(
'title',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable' => false],
'Topic Title'
)->addColumn(
'content',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'2M',
[],
'Topic Content'
)->addColumn(
'creation_time',
\Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT],
'Topic Creation Time'
)->setComment(
'Mageplaza Topic Table'
);
$installer->getConnection()->createTable($table);
$installer->endSetup();
}
}
This content is showing how the table created, you can edit it to make your own table. Please note that Magento will automatically run this file for the first time when installing the module. If you installed the module before, you will need to upgrade module and write the table create code to the UpgradeSchema.php in that folder.
After this please run this command line:
php bin/magento setup:upgrade
Now checking your database, you will see a table with name ‘mageplaza_topic’ and above columns. If this table is not created, it may be because you ran the above command line before you add content to InstallSchema.php. To fix this, you need remove the information that let Magento know your module has installed in the system. Please open the table ‘setup_module’, find and remove a row has module equals to ‘mageplaza_topic’. After this, run the command again to install the table.
This InstallSchema.php
is used to create database structure. If you want to install the data to the table which you was created, you need to use InstallData.php
file:
app/code/Mageplaza/HelloWorld/Setup/InstallData.php
Please take a look in some InstallData file in Magento to know how to use it. This’s some file you can see:
- vendor/magento/module-tax/Setup/InstallData.php
- vendor/magento/module-customer/Setup/InstallData.php
- vendor/magento/module-catalog/Setup/InstallData.php
As I said above, those install file will be used for first time install the module. If you want to change the database when upgrade module, please try to use UpgradeSchema.php
and UpgradeData.php
.
Step 2: Model
Model is a huge path of MVC architecture. In Magento 2 CRUD, models have many different functions such as manage data, install or upgrade module. In this tutorial, I only talk about data management CRUD. We have to create Model, Resource Model, Resource Model Conllection to manage data in table: mageplaza_topic
as I mentioned above.
Before create model, we need to create the interface for it. Let create the TopicInterface
:
app/code/Mageplaza/HelloWorld/Model/Api/Data/TopicInterface.php
And put this content:
<?php
namespace Mageplaza\HelloWorld\Model\Api\Data;
interface TopicInterface
{
public function getId();
public function setId();
public function getTitle();
public function setTitle();
public function getContent();
public function setContent();
public function getCreationTime();
public function setCreationTime();
}
This interface has defined the set and get method to table data which we would use when interacting with the model. This interface plays an important role when it comes time to exporting CRUD models to Magento service contracts based API.
Now we will create the model file:
app/code/Mageplaza/HelloWorld/Model/Topic.php
And this is the content of that file:
<?php
namespace Mageplaza\HelloWorld\Model;
class Topic extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\DataObject\IdentityInterface,
\Mageplaza\HelloWorld\Model\Api\Data\TopicInterface
{
const CACHE_TAG = 'mageplaza_topic';
protected function _construct()
{
$this->_init('Mageplaza\HelloWorld\Model\ResourceModel\Topic');
}
public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}
}
This model class will extends AbstractModel class Magento\Framework\Model\AbstractModel
and implements TopicInterface
and IdentityInterface
\Magento\Framework\DataObject\IdentityInterface
. The IdentityInterface will force Model class define the getIdentities()
method which will return a unique id for the model. You must only use this interface if your model required cache refresh after database operation and render information to the frontend page.
The _construct()
method will be called whenever a model is instantiated. Every CRUD model have to use the _construct() method to call _init() method. This _init() method will define the resource model which will actually fetch the information from the database. As above, we define the resource model Mageplaza\Topic\Model\ResourceModel\Topic
The last thing about model is some variable which you should you in your model:
$_eventPrefix
- a prefix for events to be triggered$_eventObject
- a object name when access in event$_cacheTag
- a unique identifier for use within caching
Step 3: Resource Model
As you know, the model file contain overall database logic, it do not execute sql queries. The resource model will do that. Now we will create the Resource Model for this table:
Mageplaza\HelloWorld\Model\ResourceModel\Topic
Content for this file:
<?php
namespace Mageplaza\HelloWorld\Model\ResourceModel;
class Topic extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
$this->_init('mageplaza_topic', 'topic_id');
}
}
Every CRUD resource model in Magento must extends abstract class \Magento\Framework\Model\ResourceModel\Db\AbstractDb
which contain the functions for fetching information from database.
Like model class, this resource model class will have required method _construct()
. This method will call _init()
function to define the table name and primary key for that table. In this example, we have table ‘mageplaza_topic’ and the primary key ‘topic_id’.
Step 4: Resource Model Collection - Get Model Collection
The collection model is considered a resource model which allow us to filter and fetch a collection table data. The collection model will be placed in:
Mageplaza\HelloWorld\Model\ResourceModel\Topic\Collection.php
The content for this file:
<?php
namespace Mageplaza\HelloWorld\Model\ResourceModel\Topic;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected function _construct()
{
$this->_init('Mageplaza\HelloWorld\Model\Topic', 'Mageplaza\HelloWorld\Model\ResourceModel\Topic');
}
}
The CRUD collection class must extends from \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
and call the _init()
method to init the model, resource model in _construct()
function.
Step 5: Factory Object
We are done with creating the database table, CRUD model, resource model and collection. So how to use them?
In this part, we will talk about Factory Object for model. As you know in OOP, a factory method will be used to instantiate an object. In Magento, the Factory Object do the same thing.
The Factory class name is the name of Model class and append with the ‘Factory’ word. So for our example, we will have TopicFactory class. You must not create this class. Magento will create it for you. Whenever Magento’s object manager encounters a class name that ends in the word ‘Factory’, it will automatically generate the Factory class in the var/generation folder if the class does not already exist. You will see the factory class in
var/generation/<vendor_name>/<module_name>/Model/ClassFactory.php
To instantiate a model object we will use automatic constructor dependency injection to inject a factory object, then use factory object to instantiate the model object.
For example, we will call the model to get data in Block. We will create a Topic block:
Mageplaza\HelloWorld\Block\Topic.php
Content for this file:
<?php
namespace Mageplaza\HelloWorld\Block;
class Topic extends \Magento\Framework\View\Element\Template
{
protected $_topicFactory;
public function _construct(
\Magento\Framework\View\Element\Template\Context $context,
\Mageplaza\HelloWorld\Model\TopicFactory $topicFactory
){
$this->_topicFactory = $topicFactory;
parent::_construct($context);
}
public function _prepareLayout()
{
$topic = $this->_topicFactory->create();
$collection = $topic->getCollection();
foreach($collection as $item){
var_dump($item->getData());
}
exit;
}
}
As you see in this block, the TopicFactory object will be created in the _construct() function. In the _prepareLayout() function, we use $topic = $this->_topicFactory->create();
to create the model object.
People also searched for:
- magento 2 CRUD
- magento 2 model
- magento 2 create model
- create Model in Magento 2
- how to create Model in Magento 2
- magento 2 get collection
- magento 2 model get collection
& Maintenance Services
Make sure your M2 store is not only in good shape but also thriving with a professional team yet at an affordable price.
Get StartedPeople also searched for
- magento 2 ebook
- magento 2 module development book
- 2.2.x, 2.3.x, 2.4.x
Stay in the know
Get special offers on the latest news from Mageplaza.
Earn $10 in reward now!