Работает на Fenrir

Модуль "Вопросы и ответы"

У нас никогда не было такого модуля, поскольку в нем не возникало потребности. Он понадобился только сейчас, для этого сайта. И теперь такой модуль у нас есть :) И есть кое-какая статистика.

Итак, для реализации модуля "Вопрос-ответ" (FAQ) понадобилось:

  • Программист, 1 шт.
  • Время, 1 час
  • PHP, 22 строки
  • XSLT, 35 строк
  • JavaScript (усиленный jQuery), 21 строка
  • Тип данных "Вопрос+ответ"
  • Jimi Hendrix, альбом "War Heroes", 9 композиций
  • Сигарета (1)
  • Кружка кофе (1)

Ниже мы представим исходный код всех частей этого модуля.

Последовательность действий такова:

  1. Придумываем, как будет работать наш модуль.
  2. Создаем раздел "FAQ" с видимостью "Скрыт".
  3. Создаем тип данных "Вопрос+ответ", добавляем ему поля "текст вопроса" (короткий текст) и "текст ответа" (длинный форматированный текст).
  4. Через админку вносим несколько вопрос-ответов в раздел FAQ.
  5. Создаем класс moduleFaq в файле /_controller/class.faq.php
  6. Пишем moduleFaq::do_list() - этот метод будет извлекать список вопросов.
  7. Добавляем в modules.xml правило, привязывающее модуль к разделу.
  8. Создаем языковые константы "свернуть", "развернуть" - чтобы не хранить языковые данные в шаблоне.
  9. Пишем шаблон - /_view/faq.xsl
  10. Добавляем JavaScript
  11. Тестируем, вносим реальные данные, меняем разделу FAQ свойство "видимость" на "Видимый".

Тип данных "Вопрос-ответ"

Настройки типа данных - свойства полей:

Тип данных "Вопрос-ответ"

Исходный код PHP-класса

Класс содержит единственный метод, отвечающий за вывод списка вопросов.

Исходный код XSLT-шаблона

Языковые константы доступны в шаблоне в виде подстановок с префиксом "lang." (например, &lang.faq.expand;).

Код JavaScript

Хотя JavaScript-код не имеет прямого отношения к CMS, приведем его здесь для полноты картины.

function fenFaq() {
	this.allCollapsed = false;
	this.className = 'collapsed';
	var _base = this;
	this.toggleAll = function () {
		$('.faq_question').each (
			function() {
				var qa = $(this);
				_base.allCollapsed ? qa.removeClass(_base.className) : qa.addClass(_base.className);
				qa.find('.arr').get(0).innerHTML = ' ' + ( !_base.allCollapsed ? '→' : '←' );
			}
		);
		_base.allCollapsed = !_base.allCollapsed;
		$('#faq_toggle').get(0).innerHTML = _base.allCollapsed ? _base.lang.expand : _base.lang.collapse;
	}
	
	this.toggleQuestion = function(id) {
		$('#qa_' + id).toggleClass(this.className);
		$('#qa_' + id + ' .arr').get(0).innerHTML = ' ' + ( $('#qa_' + id).hasClass(this.className) ? '→' : '←' );
	}
};