Раздел "Вакансии" на Нодусе

Мы создали небольшой сайт, и при этом нам практически не пришлось заниматься программированием, поскольку все необходимое уже было "из коробки". Теперь - задача посложнее. Добавим на сайт раздел "Вакансии", который сам по себе ничем не сложен и представляет собой ленту сообщений, отличающуюся от новостей только реквизитным составом и шаблонами отображения. Но такого типа данных в стандартной поставке нет, и нам придется создать его самостоятельно. Тут уже не обойтись без написания PHP-кода.

Итак, необходимо добавить на наш сайт страницу "Вакансии". На ней будет отображаться список открытых вакансий компании в котором содержится:

  • название вакантной должности;
  • предлагаемая заработная плата;
  • тип занятости.

При нажатии на название должности открывается страница, где добавляется более полная информация: требования к кандидату, обязанности, информация о компании(отдел, в который происходит набор, причинах открытия вакансии и т.п.), гарантии и бонусы работы.

Начнем с того, что добавим узел в структуру нашего сайта.

Добавление в структуру

Для того, чтобы "Вакансии" отображались в навигации, нам необходимо добавить узел в структуру навигации. Идем в админку, в раздел "Компоненты : Содержимое сайта : Структура". Добавляем узел, который будет откликаться по адресу /vacancy/. Обратите внимание, по умолчанию, этот узел добавился последним, т.е. после страницы Контакты. Однако, перемещая его мышкой, ему легко можно задать удобное расположение. Переместим узел "Вакансии" перед узлом "Контакты".

Обновим страницу - готово! В навигации появилась ссылка на страницу "Вакансии", но пока ещё сама страница не отображается.

Создание типа данных

Все типы данных в Нодусе хранятся в каталоге app/components/Nodus/app/Datatype. Чтобы добавить новый тип, создаем в нем подкаталог Vacancy. Теперь создаем модуль Type.php со следующим содержимым:

Core::load('Component.Nodus.Datatype');

class Component_Nodus_App_Datatype_Vacancy_Type extends Component_Nodus_Datatype implements Core_ModuleInterface
{

	public function title()
	{
	 	return 'Вакансия';
	}

	public function description()
	{
		return 'Открытые вакансии компании';
	}

	public function tabs()
	{
		return array(
			'default' => 'Параметры',
			'extra' => 'Доп.параметры',
		);
	}

	public function fields()
	{
		return array(
			'description' => array(
				'type' => 'textarea',
				'sqltype' => 'text',
				'style' => 'width:60%;height:100px;',
				'caption' => 'Информация компании',
				'tab' => 'default',
			),

			'money' => array(
				'type' => 'input',
				'sqltype' => 'int',
				'caption' => 'Оклад',
				'tab' => 'default',
			),

			'needs' => array(
				'type' => 'textarea',
				'sqltype' => 'text',
				'style' => 'width:60%;height:150px;',
				'caption' => 'Требования к кандидату',
				'tab' => 'default',
			),

			'duties' => array(
				'type' => 'textarea',
				'sqltype' => 'text',
				'style' => 'width:60%;height:150px;',
				'caption' => 'Обязанности',
				'tab' => 'default',
			),

			'employment' => array(
				'type' => 'input',
				'sqltype' => 'text',
				'style' => 'width:100%;height:15px;',
				'caption' => 'Тип занятости',
				'tab' => 'default',
			),

			'assurance' => array(
				'type' => 'textarea',
				'sqltype' => 'text',
				'style' => 'width:60%;height:150px;',
				'caption' => 'Мы гарантируем',
				'tab' => 'default',
			),

		);
	}

}

После этого не забываем сбросить кэш.

Как посмотреть, что же у нас получилось? Для этого идем в админку в раздел "Содержимое сайта : Материалы" и нажимаем кнопку "Добавить материал". Новый материал появился в списке.

Описание полей

Посмотрим на поля модуля Component.Nodus.App.Datatype.Vacancy.Type, какие у них есть параметры?

  • title - заголовок типа. Он нужен в основном только для админки, но никто не мешает приспособить его и для иных нужд.
  • description - краткое описание типа. Также нужен только в админке.
  • tabs - вкладки формы редактирования материала. Их может быть много, но вкладки default и extra должны быть обязательно, т.к. именно в них будут отображаться стандартные поля.
  • fields - описание полей материала.

Мы добавили все необходимые поля материла, задав их как текстовые. Но, если задуматься, поле "Тип занятости" обычно принимает два значения - полная или частичная. Поэтому было бы удобней сделать его в качестве выпадающего списка. Заменим значение атрибута "employment" на следующее:

'employment' => array(
  	'sqltype' => 'int',
  	'type' => 'select',
  	'items' => array(1 => 'Полная занятость', 2 => 'Частичная занятость'),
	'caption' => 'Тип занятости',
	'tab' => 'default',
),

Мы изменили поле в существующем типе, поэтому сбрасываем кэш.

Попробуем создать вакансию, например, руководителя отдела. Для этого добавляем материал "Вакансия" и заполняем предложенные поля. Создайте ещё несколько вакансий для наглядности.

Шаблон отображения записи

По созданному адресу (/director/) мы теперь можем посмотреть добавленную вакансию. Конечно, как отображается страница по умолчанию - совсем не то, что нам хотелось бы видеть. Попробуем исправить эту ситуацию, создав в каталоге app/components/Nodus/app/Datatype/Vacancy/ новый файл - full.phtml:

<h1><?= $item->field('title') ?></h1>
<div class="vacance-full">
<div class="description"><?= $item->field('description') ?></div><br/>
 	<div class="props">
 		<p><b>Уровень зарплаты:</b></p><div class="money"> от <?= $item->field('money') ?> рублей.</div><br/>
 		<p><b>Требования:</b></p><div class="needs"><?= $item->field('needs') ?></div><br/>
 		<p><b>Обязанности:</b></p><div class="duties"><?= $item->field('duties') ?></div><br/>
 		<p><b>Почему у нас стоит работать:</b></p><div class="assurance"><?= $item->field('assurance') ?></div><br/>
 		<p><b>Тип занятости:</b></p><div class="employment"><?= $item->field('employment') ?></div><br/>
 	</div>
 </div>

В данном случае файл шаблона должен иметь расширение phtml (как и все шаблоны) и имя, равное наименованию режима отображения записи. Наша страница по умолчанию имеет режим отображения full.

Предложенная вакансия стала намного наглядней, теперь видны все критерии. Шаблон можно изменять, как Вам больше нравится. Например, поле "Требования" можно выводить в виде маркированного списка:

 <ul>
 <?php
$str = $item->field('needs');
$row = explode("\n", $str);
foreach ($row as $value) {
	$value = trim($value);
	if (isset($value)) {
?>
	<li><?= $value ?></li>
<?php
	}
}
?></ul>

Сейчас у нас показывается единичная запись. Однако, нам надо на странице /vacancy/ выводить список всех имеющихся вакансий компании. В этом списке не удобно выводить все данные, поэтому мы будем использовать сокращенную версию, но со ссылкой на полную.

Для осуществления задуманного нам необходимо воспользоваться селектором, а точнее дополнить селектор по умолчанию.

Селектор

Нам нужно, чтобы список всех вакансий открывался по адресу /vacancy/. Открываем созданный нами ранее файл модуля Component.Nodus.App.Datatype.Vacancy.Type и дописываем в него класс Component_Nodus_App_Datatype_Vacancy_Selector:

class Component_Nodus_App_Datatype_Vacancy_Selector extends Component_Nodus_Selector
{

	public function url()
	{
		return '/vacancy/';
	}

	public function title()
	{
		return 'Наши вакансии';
	}

}

Убедимся, что все вакансии компании действительно отображаются. Заходим по адресу, который мы указали в селекторе(/vacancy/), и видим список вакансий. Наш список должен выводить лишь часть информации о вакансии, чтобы быть читаемым. Если мы посмотрим на вакансию в списке, то увидим, что у нее выводятся все поля. Как же это изменить?

Отображение записей списка

Проблема возникает в том, что отображение записей в списке происходит в режиме teaser, а такого шаблона у нас нет. Попробуем исправить эту ситуацию.

Создаем в каталоге app/components/Nodus/app/Datatype/Vacancy/ новый файл - teaser.phtml с таким содержимым:

 <h3><?= $item->field('title') ?></h3>
 	<div class="props">
 		<div class="money"><b>От <?= $item->field('money') ?> руб.</b></div>
 		<div class="employment"><?= $item->field('employment') ?></div><br/>
 	</div>

Сбросите кэш, обновите страницу. Мы видим как преобразился список. В нем выводится лишь та часть информации, которая должна заинтересовать потенциального кандидата: название вакантной должности, предлагаемая зарплата и тип занятости.

Название вакансии в этом списке представляет ссылку на полное описание с указанием требований, обязанностей и т.п. Наша задача выполнена.

Метки: Азы, Нодус
01.07.2014
Все статьи