Magento 2 Development 07: Collection and Block

0

 


Now that we have saved, let’s create a list where customer can view all of his/her blogs.

Redirection and Messages

Earlier we displayed just a simple message saying “Saved” when customer submitted form. But it will be better to redirect to the list page after saving the data.

So we have to edit the Controller/Manage/Save.php file,

<?php
namespace Webkul\BlogManager\Controller\Manage;
use Magento\Customer\Controller\AbstractAccount;
use Magento\Framework\App\Action\Context;
use Magento\Customer\Model\Session;
class Save extends AbstractAccount
{
public $blogFactory;
public $customerSession;
public $messageManager;
public function __construct(
Context $context,
\Webkul\BlogManager\Model\BlogFactory $blogFactory,
Session $customerSession,
\Magento\Framework\Message\ManagerInterface $messageManager
) {
$this->blogFactory = $blogFactory;
$this->customerSession = $customerSession;
$this->messageManager = $messageManager;
parent::__construct($context);
}
public function execute()
{
$data = $this->getRequest()->getParams();
$model = $this->blogFactory->create();
$model->setData($data);
$customer = $this->customerSession->getCustomer();
$customerId = $customer->getId();
$model->setUserId($customerId);
$model->save();
$this->messageManager->addSuccess(__('Blog saved successfully.'));
return $this->resultRedirectFactory->create()->setPath('blog/manage');
}
}

It’s a good practice to declare the member variables. So we have declared them at the stating of the class. To redirect we have used resultRedirectFactory and called setPath method with the url at which we want to redirect. As you may have noticed here we have given only two parts of the url that’s because it will autofill the missing part with “index“. So our url will become blog/manage/index.

Now let’s talk about \Magento\Framework\Message\ManagerInterface class. This is use to show messages on the page. There are four types of messages available in magento.
i) Success
ii) Error
iii) Notice
iv) Warning


2021-02-08_18-54-1

Also notice that in the addSuccess method we have passed message enclosed in __(“”) . All static text should be enclosed within __(‘some text’) so that it become translatable. Magento allows us to create translation for different languages with the help of .csv file.

Now let’s create the index action in Contoller/Manage/Index.php which will be used to show the blogs list.

<?php
namespace Webkul\BlogManager\Controller\Manage;
use Magento\Customer\Controller\AbstractAccount;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Index extends AbstractAccount
{
public function __construct(
Context $context,
PageFactory $resultPageFactory
) {
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->set(__('Blogs'));
$layout = $resultPage->getLayout();
return $resultPage;
}
}

Blocks

Here we will be showing a phtml file so we need to create layout file as view/frontend/layout/blogmanager_manage_index.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">
<update handle="customer_account"/>
<body>
<referenceContainer name="content">
<block class="Webkul\BlogManager\Block\BlogList" name="blogmanager.blog.list" template="Webkul_BlogManager::list.phtml" />
</referenceContainer>
</body>
</page>

Here everything should be familiar except the block class. Earlier we used the default block class for the Blog Add page but for the Blog List page we will create a Block class Webkul\BlogManager\Block\BlogList.

Why we need block? The need of block is to pass data to the template file. The block class contains the logical part of the view. All the data needed by the template file should come from the block. We do not write complex code in the phtml file, instead we write the complex codes in the block and pass the result to the phtml file.

Now let’s create the Block folder under the module directory. In the Block folder we need to create the block file BlogList.php as

<?php
namespace Webkul\BlogManager\Block;
class BlogList extends \Magento\Framework\View\Element\Template
{
public $blogCollection;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Webkul\BlogManager\Model\ResourceModel\Blog\CollectionFactory $blogCollection,
array $data = []
) {
$this->blogCollection = $blogCollection;
parent::__construct($context, $data);
}
public function getBlogs()
{
$collection = $this->blogCollection->create();
return $collection;
}
}

All Blocks must extend the default block class \Magento\Framework\View\Element\Template. We will use this block to load the blogs data. Note here we are using the collection \Webkul\BlogManager\Model\ResourceModel\Blog\CollectionFactory because we need to load multiple rows from the table. Just like the model the model collection also has the factory class.

Here we have getBlogs() method in which we are loading the collection and returning the whole collection. Just like model factory here also we need call the create() method to create a new object of the collection.

Now that we have created the block let’s create the list.phtml file for this block under view/frontend/templates folder.

<table>
<tr>
<th>
<?= __("Id")?>
</th>
<th>
<?= __("Title")?>
</th>
<th>
<?= __("Content")?>
</th>
</tr>
<?php
$blogs = $block->getBlogs();
foreach ($blogs as $blog) {?>
<tr>
<td>
<?= $blog->getId()?>
</td>
<td>
<?= $blog->getTitle()?>
</td>
<td>
<?= substr($blog->getContent(), 0, 20).'...'?>
</td>
</tr>
<?php } ?>
</table>

The <?= ?> is nothing but a shorthand notation for <?php echo ?>. You can find about it in the php manual. I have already told about the __(“”), it’s used for translation.

Now see the important line $blogs = $block->getBlogs(); here we are calling the getBlogs() function of the block which will return the blogs collection. Remember I told you that collection is collection of models, so when we loop over the collection with a foreach loop then we will get a model in each iteration. That means in each iteration we will get a row from the table.

The $blog->getId() will return the entity_id that means it acts as getEntityId() that’s because in the model we have written this method,

2021-02-08_20-32

Just like the setters that we saw in the previous blog the getters get internally managed, we just have to use the camelCase naming convention for each column. So we can use getTitle()getContent() to access the title and content column respectively, even though we have not written these methods in the model file.

Now when you submit the add blog form you will be redirected to blog list page with a success message like,

2021-02-08_17-51

Let’s create a customer navigation link for this page also, we have to edit view/frontend/layout/customer_account.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="customer_account_navigation">
<block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-blog-add" after="-" >
<arguments>
<argument name="label" xsi:type="string" translate="true">Add Blog</argument>
<argument name="path" xsi:type="string">blog/manage/add</argument>
</arguments>
</block>
<block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-blog-list" before="customer-account-navigation-blog-add" >
<arguments>
<argument name="label" xsi:type="string" translate="true">Blogs</argument>
<argument name="path" xsi:type="string">blog/manage</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>

Here in the block node we have added before=”customer-account-navigation-blog-add” so it will add the blog list menu before the blog add menu. You will be able to see the Blogs link in the customer navigation,

2021-02-09_11-43

PS. We can get the collection from the model class also. When we call the $model->getCollection() it returns the collection of the model.

PS. Just like setData the model and collections have getData, which returns the data in associative array format. So during development or debugging when we have to view data, we use echo ‘<pre>; print_r($collection->getData()); die; which prints out the data in nice viewable format.

Folder structure till now,

2021-02-09_11-46

okk

Post a Comment

0Comments
Post a Comment (0)
To Top