Yay, Magento 2 is officially out!
Great news indeed. My name is Alex, and I’m a Magento specialist at Amasty. For the last few months I’ve been busy building Magento 2 extensions, and today I wanted to share an instruction on building a simple custom module in Magento 2.
What we’re going to build
This Magento 2 extension is going to have a model with undefined data, which will be stored in the database. And we’ll display the values on the product page.
What’s more, we are going to create several settings to change the extension’s behavior. Nothing complicated, so let’s start!
Create configuration
The first step is to install Magento 2 and create a catalog to store the extension files. In Magento 2 files are not distributed through the folders and have a modular structure.
The files of the newly created extension will be in this catalog:
app\code\Amasty\HelloWorld/
Here Amasty is the name of the company that built the extension, HelloWorld is the name of the Magento 2 extension we are creating at the moment.
Now it’s time to actually code the extension. Catalogs purposes have slightly changed in comparison with the first versions of Magento.
Extension configuration is located in etc folder, as before.
Let’s create app\code\Amasty\ HelloWorld \etc catalog in Magento 2 and add a module.xml file inside it. This is the file where we are going to set our extension name and its version.
The file looks like this:
Now let’s check if Magento 2 sees the extension.
Run the following console command:
php bin/magento setup:upgrade
But there’s no result. To fix it, let’s create registration.php file in the root folder of the extension and put the following code inside:
This is done to tell Magento 2 that it should run the extension from the current directory.
Now go and clear Magento cache, and you’ll see that our extension is working now:
Create settings
Now let’s create some settings for the new extension. To do that, add adminhtml catalog to etc catalog. It will contain configuration files for backend.
The first file we need here is routes.xml for frontName and id setting, which is used to define queries for the extension. It is done by the following piece of code:
Now let’s configure the extension settings. As in the previous version, they’re located in the system.xml file, but the xml markup is slightly different in Magento 2.
I’m creating the three most popular settings as an example: a text setting, yes/no setting and a setting with custom values.
Have a look at the config file contents and what it actually means:
Add a new section to the settings block using <tab>. Set the unique ID and the name of the settings section inside. It is done because we have a very high possibility of using several apps from the same vendor on a single site.
Add the new <section id="amasty_helloworld"> , again, with the unique ID, and set the necessary parameters, such as type, translation fields, order, label, the block for which the section is added, and so on. And then add the settings just inside the section. They will be divided into groups (one group in our case). The groups are defined by <group>, and the fields are set by <field>. We have already created three settings and pointed out types, labels, visibility, translation, comments and the data model.
In our case the third setting implies custom data, so we pointed out a separate data model for it. To do that, you need to create Amasty\HelloWorld\Model\Source\ Align model, where we will set the needed choice variants. The extension should be defined from \Magento\Framework\Option\ArrayInterface interface, and you need to redefine toOptionArray() and toArray() methods as well.
Let’s check the result. Open your Magento 2 backend, go to Stores - Configuration. Boom, we can see the settings!
Now, as we created the settings, we should set default values for the options. To do that, create a config.xml in the etc catalog and put the default values in accordance with system.xml in there.
→ If you need help to configure the Amasty module according to your needs, check out our Configuration Service. You will be provided professional Magento web configuration service for any available extension. After the configuration of the module, testing is carried out for its correct operation.
Frontend output
Block
Now let’s try to show something on the frontend, i.e. to create a block and a template for it, and then to show this block on the product page.
Create a class of \Amasty\HelloWorld\Block\Catalog\Product\HelloWorld block, which should inherit from Magento class \Magento\Framework\View\Element\Template
We are going to use the parent constructor. Here’s how it will look like for this block:
Template
Let’s create a simple template and put it in the following catalog:
Amasty\HelloWorld\view\frontend\templates\product\hello.phtml
You can see that in Magento 2 we have the view catalog, where we’re going to store the information, which was scattered in several theme catalogs, such as templates, layouts, scripts, styles, before.
Put this simple text inside:
<?=__('Hello World');?>
As we see from the example, now you can perform translation in Magento using __() without a separate class. And the translation for this line will be pulled from Amasty\HelloWorld\i18n\en_US.csv
We have created the template, now let’s show it on the product page.
Layout
Time to create the layout! Now we are creating not a unique layout for all the pages, but a separate file for each page. As we will show the block on the product page, let’s create a layout with the following name:
Amasty\HelloWorld\view\frontend\layout\catalog_product_view.xml
Put this code inside:
As an example, we added the new block into product.info.main block in the layout code and added the styles file to use when showing on frontend. The styles file has the following address:
Amasty\HelloWorld\view\frontend\web\css\hello.css
Refresh the product page:
Voila, the block is there!
Now let’s change the look of the block – and add the helper initialization to it.
The extension constructor looks like this:
The helper from the created block is used as $this->_helper variable.
Helper
Create the helper in the following catalog:
Amasty\HelloWorld\Helper\Data.php
Add \Magento\Framework\App\Config\ScopeConfigInterface interface object initialization to the helper, it works to receive the data from configuration.
Now the file looks like this:
In this piece of code you can see that three functions for getting extension configuration from settings section were created.
Let’s use these functions in the block and change the template:
Now the block is displayed taking the settings into account:
Model creation
Create installation script
As in the 1.x versions of Magento, you need to create the installation file to use your own table. We are going to describe creating of a simple table with several fields. The file should be created here: Amasty\HelloWorld\Setup\InstallSchema.php
And this is its contents:
You can see that we are creating an 'amasty_helloworld' table with one field of integer type and two fields of text type.
Model creation
As in the previous Magento version, we need to create three classes to work with the model: the model itself, the resource model and the collection.
Let’s create a Amasty\HelloWorld\Model\HelloWorld.php file and use the following initialization:
[php]
/**
* Copyright © 2015 Amasty. All rights reserved.
*/
namespace Amasty\HelloWorld\Model\ResourceModel;
class HelloWorld extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
/**
* Model Initialization
*
* @return void
*/
protected function _construct()
{
$this->_init('amasty_helloworld', 'id');
}
}
[/php]
We just set the Magento helper constructor for the model here. In fact, there is no great difference from the first Magento versions on this step. The resource model and the collection are stored in the following catalogs:
Amasty\HelloWorld\Model\ResourceModel\HelloWorld.php
Amasty\HelloWorld\Model\ResourceModel\HelloWorld\Collection.php
These files’ listings are of no particular interest. Create a simple function in the block we’re working with:
[php]
public function getCollection()
{
$model = $this->_objectManager->create('Amasty\HelloWorld\Model\HelloWorld');
$collection = $model->getCollection();
return $collection;
}
[/php]
and display it inside the template:
[php]
<?php foreach($this->getCollection() as $item):?>
<label><?= __("Title: ") . $item->getLabel()?></label> -- <label><?= __("Value: ") . $item->getValue();?></label>
<?php endforeach;?>
[/php]
Now update the product page: it works!
Should you have any questions about this process of Magento 2 extension creation, please ask them in comments. Good luck to you!