Before begin this practical, you must read previous lessons of the training
Specifications
– Create view job page
– The page title will contain job’s title and department’s name
– Create view department page
– This page will contain a list of jobs associated to the viewing department
– We will use the same CSS we created before
– I will not give css styles, so you can customize your pages as you like
– I will not give traductions
Here is my view job page :
And for a department :
And now, play on
With the previous unit of the traning, you will be able to develop the specifications of this practical.
…
…
…
…
…
…
…
…
…
…
…
…
Have you finished ?
Correction
We will find all the files content to compare with what you did !
app/code/Maxime/Jobs/view/frontend/layout/jobs_job_view.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" layout="2columns-right"> <head> <css src="Maxime_Jobs::jobs.css"/> </head> <body> <referenceContainer name="content"> <block class="Maxime\Jobs\Block\Job\View" name="jobs_job_view" template="jobs/job/view.phtml" /> </referenceContainer> </body> </page>
app/code/Maxime/Jobs/view/frontend/layout/jobs_department_view.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" layout="2columns-right"> <head> <css src="Maxime_Jobs::jobs.css"/> </head> <body> <referenceContainer name="content"> <block class="Maxime\Jobs\Block\Department\View" name="jobs_department_view" template="jobs/department/view.phtml" /> </referenceContainer> </body> </page>
app/code/Maxime/Jobs/Controller/Job/View.php
<?php namespace Maxime\Jobs\Controller\Job; class View extends \Magento\Framework\App\Action\Action { /** * @var \Maxime\Jobs\Model\Job */ protected $_model; /** * @param \Magento\Framework\App\Action\Context $context * @param \Maxime\Jobs\Model\Job $model */ public function __construct( \Magento\Framework\App\Action\Context $context, \Maxime\Jobs\Model\Job $model ) { $this->_model = $model; parent::__construct($context); } public function execute() { // Get param id $id = $this->getRequest()->getParam('id'); $model = $this->_model; // No id, redirect if(empty($id)){ $resultRedirect = $this->resultRedirectFactory->create(); return $resultRedirect->setPath('*/*/'); } $model->load($id); // Model not exists with this id, redirect if (!$model->getId()) { $resultRedirect = $this->resultRedirectFactory->create(); return $resultRedirect->setPath('*/*/'); } $this->_view->loadLayout(); $this->_view->getLayout()->initMessages(); $this->_view->renderLayout(); } }
app/code/Maxime/Jobs/Controller/Department/View.php
<?php namespace Maxime\Jobs\Controller\Department; class View extends \Magento\Framework\App\Action\Action { /** * @var \Maxime\Jobs\Model\Department */ protected $_model; /** * @param \Magento\Framework\App\Action\Context $context * @param \Maxime\Jobs\Model\Department $model */ public function __construct( \Magento\Framework\App\Action\Context $context, \Maxime\Jobs\Model\Department $model ) { $this->_model = $model; parent::__construct($context); } public function execute() { // Get param id $id = $this->getRequest()->getParam('id'); $model = $this->_model; // No id, redirect if(empty($id)){ $resultRedirect = $this->resultRedirectFactory->create(); return $resultRedirect->setPath('*/*/'); } $model->load($id); // Model not exists with this id, redirect if (!$model->getId()) { $resultRedirect = $this->resultRedirectFactory->create(); return $resultRedirect->setPath('*/*/'); } $this->_view->loadLayout(); $this->_view->getLayout()->initMessages(); $this->_view->renderLayout(); } }
app/code/Maxime/Jobs/Block/Job/View.php
<?php namespace Maxime\Jobs\Block\Job; class View extends \Magento\Framework\View\Element\Template { protected $_job; protected $_department; /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Maxime\Jobs\Model\Job $job * @param \Maxime\Jobs\Model\Department $department * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Maxime\Jobs\Model\Job $job, \Maxime\Jobs\Model\Department $department, array $data = [] ) { $this->_job = $job; $this->_department = $department; parent::__construct( $context, $data ); } /** * @return $this */ protected function _prepareLayout() { parent::_prepareLayout(); // Get job and department $job = $this->getLoadedJob(); $department = $this->getLoadedDepartment(); // Title is job's title and department's name $title = $job->getTitle() .' - '.$department->getName(); $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' => __('We are hiring'), 'title' => __('We are hiring'), 'link' => $this->getListJobUrl() // No link for the last element ] ); $breadcrumbsBlock->addCrumb( 'job', [ '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 _getJob() { if (!$this->_job->getId()) { // our model is already set in the construct // but I put this method to load in case the model is not loaded $entityId = $this->_request->getParam('id'); $this->_job = $this->_job->load($entityId); } return $this->_job; } public function getLoadedJob() { return $this->_getJob(); } protected function _getDepartment() { if (!$this->_department->getId()) { // Get the job to retrieve department_id $job = $this->getLoadedJob(); // Load department with id $this->_department->load($job->getDepartmentId()); } return $this->_department; } public function getLoadedDepartment() { return $this->_getDepartment(); } public function getListJobUrl(){ return $this->getUrl('jobs/job'); } public function getDepartmentUrl($job){ if(!$job->getDepartmentId()){ return '#'; } return $this->getUrl('jobs/department/view', ['id' => $job->getDepartmentId()]); } }
app/code/Maxime/Jobs/Block/Department/View.php
<?php namespace Maxime\Jobs\Block\Department; class View extends \Magento\Framework\View\Element\Template { protected $_jobCollection = null; protected $_department; protected $_job; /** * @param \Magento\Framework\View\Element\Template\Context $context * @param \Maxime\Jobs\Model\Department $department * @param \Maxime\Jobs\Model\Job $job * @param array $data */ public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Maxime\Jobs\Model\Department $department, \Maxime\Jobs\Model\Job $job, array $data = [] ) { $this->_department = $department; $this->_job = $job; parent::__construct( $context, $data ); } /** * @return $this */ protected function _prepareLayout() { parent::_prepareLayout(); // Get department $department = $this->getLoadedDepartment(); // Title is department's name $title = $department->getName(); $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' => __('We are hiring'), 'title' => __('We are hiring'), 'link' => $this->getListJobUrl() // No link for the last element ] ); $breadcrumbsBlock->addCrumb( 'job', [ '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 _getDepartment() { if (!$this->_department->getId()) { // our model is already set in the construct // but I put this method to load in case the model is not loaded $entityId = $this->_request->getParam('id'); $this->_department = $this->_department->load($entityId); } return $this->_department; } public function getLoadedDepartment() { return $this->_getDepartment(); } public function getListJobUrl(){ return $this->getUrl('jobs/job'); } protected function _getJobsCollection(){ if($this->_jobCollection === null && $this->_department->getId()){ $jobCollection = $this->_job->getCollection() ->addFieldToFilter('department_id', $this->_department->getId()) ->addStatusFilter($this->_job, $this->_department); $this->_jobCollection = $jobCollection; } return $this->_jobCollection; } public function getLoadedJobsCollection() { return $this->_getJobsCollection(); } public function getJobUrl($job){ if(!$job->getId()){ return '#'; } return $this->getUrl('jobs/job/view', ['id' => $job->getId()]); } }
app/code/Maxime/Jobs/view/frontend/templates/jobs/job/view.phtml
<?php $job = $this->getLoadedJob(); $department = $this->getLoadedDepartment(); ?> <?php if($job->getId()) : ?> <div class="job-view-wrapper"> <div class="department_name"> <?php echo __('Department : '); ?> <a href="<?php echo $this->getDepartmentUrl($job); ?>" title="<?php echo $department->getName(); ?>"> <?php echo $department->getName(); ?> </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> </div> <?php else : ?> <?php echo __('This job does not exist'); ?> <?php endif; ?>
app/code/Maxime/Jobs/view/frontend/templates/jobs/department/view.phtml
<?php $department = $this->getLoadedDepartment(); $jobCollection = $this->getLoadedJobsCollection(); $iterator = 1; $total = $jobCollection->count(); ?> <?php if($department->getId()) : ?> <div class="department-view-wrapper"> <div class="description"><?php echo $department->getDescription(); ?></div> </div> <?php if($total): ?> <h2><?php echo __('Jobs for this department'); ?></h2> <?php foreach($jobCollection AS $job): ?> <ol class="jobs list"> <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> </ol> <?php $iterator++; ?> <?php endforeach; ?> <?php endif; ?> <?php else : ?> <?php echo __('This department does not exist'); ?> <?php endif; ?>
I think I put all the files 🙂
If I forget one or if you saw an error, you can write a comment to warn me.
You can also write a comment if you have some questions 😉
On the next part, we will learn how to add some configuration on Magento backoffice and what are helpers and events !