Before create the template file, we have to create routes, and controller of our module. Our block will have new methods, and our templates will be dynamical !
File : routes.xml
Create the file:
app/code/Maxime/Jobs/etc/frontend/routes.xml
With this content:
<?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="jobs" frontName="jobs"> <module name="Maxime_Jobs" /> </route> </router> </config>
Frontend Controller creation
You guess the filename is :
app/code/Maxime/Jobs/Controller/Job/Index.php
Which contains :
<?php namespace Maxime\Jobs\Controller\Job; class Index extends \Magento\Framework\App\Action\Action { public function execute() { $this->_view->loadLayout(); $this->_view->getLayout()->initMessages(); $this->_view->renderLayout(); } }
Layout creation
The path of the file is :
app/code/Maxime/Jobs/view/frontend/layout/jobs_job_index.xml
With this content :
<?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" layout="2columns-right"> <body> <referenceContainer name="content"> <block class="Maxime\Jobs\Block\Job\ListJob" name="jobs_list" template="jobs/list.phtml" /> </referenceContainer> </body> </page>
Block creation
This part is more interesting 🙂
Create the file
app/code/Maxime/Jobs/Block/Job/ListJob.php
We have to put ListJob because List is a keyword for PHP
Put this content, I will explain it later :
<?php namespace Maxime\Jobs\Block\Job; class ListJob extends \Magento\Framework\View\Element\Template { protected $_job; protected $_department; protected $_resource; protected $_jobCollection = null; /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Maxime\Jobs\Model\Job $job * @param \Maxime\Jobs\Model\Department $department * @param \Magento\Framework\App\ResourceConnection $resource * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Maxime\Jobs\Model\Job $job, \Maxime\Jobs\Model\Department $department, \Magento\Framework\App\ResourceConnection $resource, array $data = [] ) { $this->_job = $job; $this->_department = $department; $this->_resource = $resource; parent::__construct( $context, $data ); } /** * @return $this */ protected function _prepareLayout() { parent::_prepareLayout(); // You can put these informations editable on BO $title = __('We are hiring'); $description = __('Look at the jobs we have got for you'); $keywords = __('job,hiring'); $this->getLayout()->createBlock('Magento\Catalog\Block\Breadcrumbs'); if ($breadcrumbsBlock = $this->getLayout()->getBlock('breadcrumbs')) { $breadcrumbsBlock->addCrumb( 'jobs', [ 'label' => $title, 'title' => $title, 'link' => false // No link for the last element ] ); } $this->pageConfig->getTitle()->set($title); $this->pageConfig->setDescription($description); $this->pageConfig->setKeywords($keywords); $pageMainTitle = $this->getLayout()->getBlock('page.main.title'); if ($pageMainTitle) { $pageMainTitle->setPageTitle($title); } return $this; } protected function _getJobCollection() { if ($this->_jobCollection === null) { $jobCollection = $this->_job->getCollection() ->addFieldToSelect('*') ->addFieldToFilter('status', $this->_job->getEnableStatus()) ->join( array('department' => $this->_department->getResource()->getMainTable()), 'main_table.department_id = department.'.$this->_job->getIdFieldName(), array('department_name' => 'name') ); $this->_jobCollection = $jobCollection; } return $this->_jobCollection; } public function getLoadedJobCollection() { return $this->_getJobCollection(); } public function getJobUrl($job){ if(!$job->getId()){ return '#'; } return $this->getUrl('jobs/job/view', ['id' => $job->getId()]); } public function getDepartmentUrl($job){ if(!$job->getDepartmentId()){ return '#'; } return $this->getUrl('jobs/department/view', ['id' => $job->getDepartmentId()]); } }
prepareLayout method create the breadcrumbs and set metas datas of the page.
_getJobCollection method retrieve the collection to get. If it’s already loaded, we return the class attribute. For the addFieldToFilter and join call, we will see that more precisly on the next lesson.
getLoadedJobCollection is public, this is the one will be called on the template file.
getJobUrl method allow us to retrieve the job’s URL
getDepartmentUrl method is the same for departments.
List template creation
Create the file :
app/code/Maxime/Jobs/view/frontend/templates/jobs/list.phtml
With this content :
<?php $jobCollection = $this->getLoadedJobCollection(); $iterator = 1; $total = $jobCollection->count(); ?> <div class="job-wrapper"> <ol class="jobs list"> <?php foreach($jobCollection AS $job): ?> <li class="item<?php echo ($iterator == 1) ? ' first' : ''; ?><?php echo ($total == $iterator) ? ' last' : ''; ?>"> <div class="title"> <a href="<?php echo $this->getJobUrl($job); ?>" title="<?php echo $job->getTitle(); ?>"> <?php echo $job->getTitle(); ?> </a> </div> <div class="department_name"> <?php echo __('Department : '); ?> <a href="<?php echo $this->getDepartmentUrl($job); ?>" title="<?php echo $job->getDepartmentName(); ?>"> <?php echo $job->getDepartmentName(); ?> </a> </div> <div class="type"><?php echo $job->getType(); ?></div> <div class="location"><?php echo $job->getLocation(); ?></div> <div class="date"><?php echo $this->formatDate($job->getDate()); ?></div> <div class="description"><?php echo $job->getDescription(); ?></div> </li> <?php $iterator++; ?> <?php endforeach; ?> </ol> </div>
Nothing difficult with this code, you can see the formatDate which convert the date with the format setted on Magento configuration for the store. For example, english date format and french date format are different.
We create the HTML structure with some class which can be useful for the CSS rules.
We should have this render :
On the HTML code, meta-datas are present :
<meta name="description" content="Look at the jobs we have got for you"/> <meta name="keywords" content="job,hiring"/> <title>We are hiring</title>
Next step, I will explain how to use Magento collections and Zend selects.
Hi,
it’s a great tutorial, the only one which helped me to get through with well understanding.
I’ve now displayed the html, but what I would like to know is: how can I get for example all department names dislayed in a dropdown ON THE FRONTEND?
Hii,
please can you provide zip file of this module. Actually i didn’t get Database table,
Thank you