Formation Magento 2 : Travaux Pratiques 2

Avant de commencer ce TP, vous devez avoir suivi les cours précédents de la formation

Cahier des charges

– Créer la page de visualisation d’un job
– Le titre de la page sera le titre du poste et le nom de son département
– Créer la page de visualisation d’un département
– La page de visualisation d’un département comportera également une liste des jobs associés à ce département
– Nous garderons le même fichier CSS que précédemment pour ces pages
– Laissez libre cours à votre imagination, je ne ferai aucun ajout de CSS, mais vous vous pouvez le faire si vous le souhaitez 🙂
– Ma boutique est en anglais, je vous laisse mettre en place les traductions si besoin

Voici ma page de visualisation d’un job :

job_view

Et celle d’un department :

department_view

A vous de jouer !

Reprenez les deux précédents chapitres, ainsi que les éléments que je vous ai fourni ci-dessus.
Vous ne devriez pas rencontrer de grandes difficultés, mais il faut quand même réfléchir un minimum !












Alors vous avez fini ?

Correctif

Voici les fichiers un par un et leur contenu !

app/code/Maxime/Jobs/view/frontend/layout/jobs_job_view.xml

Afficher

<?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>

[collapse]


app/code/Maxime/Jobs/view/frontend/layout/jobs_department_view.xml

Afficher

<?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>

[collapse]


app/code/Maxime/Jobs/Controller/Job/View.php

Afficher

<?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();
    }
}

[collapse]


app/code/Maxime/Jobs/Controller/Department/View.php

Afficher

<?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();
    }
}

[collapse]


app/code/Maxime/Jobs/Block/Job/View.php

Afficher

<?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()]);
    }
}

[collapse]


app/code/Maxime/Jobs/Block/Department/View.php

Afficher

<?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()]);
    }
}

[collapse]


app/code/Maxime/Jobs/view/frontend/templates/jobs/job/view.phtml

Afficher

<?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; ?>

[collapse]


app/code/Maxime/Jobs/view/frontend/templates/jobs/department/view.phtml

Afficher

<?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; ?>

[collapse]


Voilà je pense que tous les fichiers sont présents 🙂

Si j’en ai oublié un ou si vous remarquez une erreur, n’hésitez pas à en faire part dans les commentaires.
Si vous avez des questions également 😉

La prochaine partie sera consacrée à la mise en place de configuration dans le BO, aux helpers et aux événements !

Continuer la formation
Revenir à la partie précédente
TP : Page visualisation de job et department
Share on FacebookTweet about this on TwitterShare on Google+Email this to someone
Taggé sur :

3 thoughts on “TP : Page visualisation de job et department

  • 27/09/2016 à 16:57
    Permalink

    Bonjour, j’ai toujours la même erreur quand je clique sur une offre ou sur un département
    L’erreur est :
    La page « mon nom de de domaine » ne fonctionne pas

    Impossible de traiter cette demande via « mon nom de domaine » à l’heure actuelle.

    Je ne vois pas ce que j’ai pu oublié.
    Merci pour votre tuto qui m’aide énormément

    Répondre
    • 28/09/2016 à 08:30
      Permalink

      Problème résolu, dans mes vues, je m’étais trompé de chemin en appelant le Bloc

      Répondre
  • 10/10/2017 à 14:30
    Permalink

    Bonjour,
    Petite erreur si on saisi un département qui n’existe pas.
    Dans template department/view.phtml, placer l’affectation de la variable $total après la condition qui vérifie l’existence de la catégorie, sinon ça marche au poil, merci 🙂

    Répondre

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous utilisons des cookies afin de nous assurer de vous proposer la meilleure expérience sur ce site.
Ok