Создаем основные файлы и классы модуля

Для того, чтобы модуль корректно зарегистрировался в системе и мы смогли сосредоточится на разработке его функционала, создадим необходимые файлы и опишем изначальную структуру классов:

  1. install.php

    Отвечает за регистрацию модуля в системе. В файле install.php находится массив $INFO, который содержит ключи, которые будут внесены в настройки системы, чтобы обеспечить функционирование модуля и массив $COMPONENTS, содержащий список компонентов модуля.

    /**
     * @var array $INFO реестр модуля
     */
    $INFO = [
    	'name' => 'dummy', // Имя модуля
    	'config' => '1', // У модуля есть настройки
    	'default_method' => 'page', // Метод по умолчанию в клиентской части
    	'default_method_admin' => 'pages', // Метод по умолчанию в административной части
    	'func_perms' => 'Группы прав на функционал модуля', // Группы прав
    	'func_perms/guest' => 'Гостевые права', // Гостевая группа прав
    	'func_perms/admin' => 'Административные права', // Административная группа прав
    	'paging/' => 'Настройки постраничного вывода', // Группа настроек
    	'paging/pages' => 25, // Настройка количества выводимых страниц
    	'paging/objects' => 25, // Настройка количества выводимых объектов
    ];
    
    /**
     * @var array $COMPONENTS файлы модуля
     */
    $COMPONENTS = [
    	'./classes/components/dummy/admin.php',
    	'./classes/components/dummy/class.php',
    	'./classes/components/dummy/customAdmin.php',
    	'./classes/components/dummy/customMacros.php',
    	'./classes/components/dummy/i18n.php',
    	'./classes/components/dummy/install.php',
    	'./classes/components/dummy/lang.php',
    	'./classes/components/dummy/macros.php',
    	'./classes/components/dummy/permissions.php',
    ];
    

    Описание обязательных настроек:

    $INFO['name']

    Имя модуля (латинское), будет использоваться системой, должно совпадать с именем папки модуля. Имя модуля должно быть уникальным, рекомендуем добавлять к нему префикс с названием вашей организации. Если проигнорировать данную рекомендацию, то может возникнуть коллизия - другая организация может опубликовать модуль с таким же именем на umi.market, в таком случае ваш модуль при переактивации системы отключится, так как он не был приобретен.

    $INFO['default_method']

    Метод, который будет вызываться по умолчанию в клиентской части

    $INFO['default_method_admin']

    Метод, который будет вызываться по умолчанию в административной части

    $INFO['func_perms']

    Массив, определяющий группы прав нашего модуля. Это те группы, которые отображаются в настройках пользователя и влияют на доступ к функционалу модуля. Более подробно права будут рассмотрены далее.

    $COMPONENTS

    Массив, содержащий пути к файлам, необходимым для работы нашего модуля.

  2. class.php

    Основной файл, содержащий класс, который представляет собой модуль. Этот класс должен быть унаследован от абстрактного класса def_module и должен иметь имя, соответствующее имени модуля. Класс модуля может подключать методы других абстрактных классов, в зависимости от режима работы системы. Это позволяет экономить ресурсы и логически разделить административные методы и клиентские методы-макросы.

    При работе с модулем мы пользуемся экземпляром этого класса. Каждый публичный метод этого класса может являться макросом.

    
    class dummy extends def_module {
    
    	/**
    	 * Конструктор
    	 */
    	public function __construct() {
    		parent::__construct();
                    
                    // В зависимости от режима работы системы
    		if (cmsController::getInstance()->getCurrentMode() == "admin") {
    			// Создаем вкладки административной панели
                            $this->initTabs();
                            // Подключаем классы функционала административной панели
    			$this->includeAdminClasses();
    		} else {
                            // Подключаем классы клиентского функционала
    			$this->includeGuestClasses();
    		}
    
    		$this->includeCommonClasses();
    	}
    
    	/**
    	 * Возвращает ссылки на форму редактирования страницы модуля и
    	 * на форму добавления дочернего элемента к странице.
    	 * @param int $element_id идентификатор страницы модуля
    	 * @param string|bool $element_type тип страницы модуля
    	 * @return array
    	 */
    	public function getEditLink($element_id, $element_type = false) {
    		return [
    			false,
    			$this->pre_lang . "/admin/dummy/editPage/{$element_id}/"
    		];
    	}
    
    	/**
    	 * Возвращает ссылку на редактирование объектов в административной панели
    	 * @param int $objectId ID редактируемого объекта
    	 * @param string|bool $type метод типа объекта
    	 * @return string
    	 */
    	public function getObjectEditLink($objectId, $type = false) {
    		return $this->pre_lang . "/admin/dummy/editObject/"  . $objectId . "/";
    	}
    
    	/**
    	 * Создает вкладки административной панели модуля
    	 */
    	protected function initTabs() {
    		$configTabs = $this->getConfigTabs();
    
    		if ($configTabs instanceof iAdminModuleTabs) {
    			$configTabs->add("config");
    		}
    
    		$commonTabs = $this->getCommonTabs();
    
    		if ($commonTabs instanceof iAdminModuleTabs) {
    			$commonTabs->add('pages');
    			$commonTabs->add('objects');
    		}
    	}
    
    	/**
    	 * Подключает классы функционала административной панели
    	 */
    	protected function includeAdminClasses() {
    		$this->__loadLib("admin.php");
    		$this->__implement("DummyAdmin");
    
    		$this->loadAdminExtension();
    
    		$this->__loadLib("customAdmin.php");
    		$this->__implement("DummyCustomAdmin", true);
    	}
    
    	/**
    	 * Подключает классы функционала клиентской части
    	 */
    	protected function includeGuestClasses() {
    		$this->__loadLib("macros.php");
    		$this->__implement("DummyMacros");
    
    		$this->loadSiteExtension();
    
    		$this->__loadLib("customMacros.php");
    		$this->__implement("DummyCustomMacros", true);
    	}
    
    	/**
    	 * Подключает общие классы функционала
    	 */
    	protected function includeCommonClasses() {
    		$this->loadCommonExtension();
    		$this->loadTemplateCustoms();
    	}
    };
    

    Обратите внимание на метод getEditLink. Этот метод должен присутствовать, если наш модуль работает со страницами. Этот метод указывает системе где находятся обработчики на добавление и редактирование нашей страницы. Используется, например, при построении дерева (в модуле "Структура"), в панели быстрого редактирования на клиентской части. Далее мы поговорим об этом методе более подробно, а так же "научим" систему "распознавать" наши страницы для отображения в панели быстрого редактирования. Аналогичные методы можно определить для получения ссылки на редактирование объектов и типов данных, с помощью методов getObjectEditLink() и getObjectTypeEditLink().

  3. admin.php

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

    Этот файл мы подгружаем в классе модуля class.php (см. выше) только в том случае, если пользователь находится в режиме администрирования. Административный класс должен использовать трейт baseModuleAdmin.

    Пример реализации получения, удаления, переключения активности списка страниц, создания и редактирования страницы:

    
    class DummyAdmin {
    
    	use baseModuleAdmin;
    	/**
    	 * @var dummy $module
    	 */
    	public $module;
    
    	/**
    	 * Возвращает список страниц
    	 * @return bool
    	 * @throws coreException
    	 * @throws selectorException
    	 */
    	public function pages() {
                    // Устанавливаем тип данных - список
    		$this->setDataType('list');
                    // Устанавливаем тип операции - просмотр
    		$this->setActionType('view');
    
                    // Если метод вызван не через /.xml - ничего не возвращаем
    		if ($this->module->ifNotXmlMode()) {
    			$this->setDirectCallError();
    			$this->doData();
    			return true;
    		}
    
                    // Получаем настройки постраничного вывода
    		$limit = getRequest('per_page_limit');
    		$pageNumber = (int) getRequest('p');
    		$offset = $limit * $pageNumber;
    
                    // Делаем выборку страниц модуля
    		$pages = new selector('pages');
    		$pages->types('object-type')->name('dummy', 'page');
    		$pages->limit($offset, $limit);
    
                    // Применяем фильтры и сортировку
    		selectorHelper::detectHierarchyFilters($pages);
    		selectorHelper::detectWhereFilters($pages);
    		selectorHelper::detectOrderFilters($pages);
    
    		$result = $pages->result();
    		$total = $pages->length();
    
                    // Устанавливаем результаты работы метода
    		$this->setDataRange($limit, $offset);
    		$data = $this->prepareData($result, 'pages');
    		$this->setData($data, $total);
    		$this->doData();
    	}
    
    	/**
    	 * Возвращает данные для построения формы добавления страницы модуля.
    	 * Если передан ключевой параметр $_REQUEST['param2'] = do, то добавляет страницу.
    	 * @throws coreException
    	 * @throws expectElementException
    	 * @throws wrongElementTypeAdminException
    	 */
    	public function addPage() {
                    // Валидируем родительскую страницу
    		$parent = $this->expectElement('param0');
    		$type = (string) getRequest("param1");
    		$mode = getRequest('param2');
    
                    // Оформляем данные
    		$inputData = [
    			'type'		=> $type,
    			'parent'	=> $parent,
    			'type-id'	=> getRequest('type-id'),
    			'allowed-element-types' => [
    				'page'
    			]
    		];
    
                    // Если передан ключевой параметр 
    		if ($mode == 'do') {
                            // Добавляем страницу
    			$this->saveAddedElementData($inputData);
                            // Делаем перенаправления, в зависимости от режима кнопки "Добавить"
    			$this->chooseRedirect();
    		}
    
                    // Устанавливаем тип данных - форма
    		$this->setDataType('form');
                    // Устанавливаем тип операции - создание
    		$this->setActionType('create');
                    // Устанавливаем результаты работы метода
    		$data = $this->prepareData($inputData, 'page');
    		$this->setData($data);
    		$this->doData();
    	}
    
    	/**
    	 * Возвращает данные для построения формы редактирования страницы модуля.
    	 * Если передан ключевой параметр $_REQUEST['param1'] = do, то сохраняет изменения страницы.
    	 * @throws coreException
    	 * @throws expectElementException
    	 * @throws wrongElementTypeAdminException
    	 */
    	public function editPage() {
                    // Валидируем редактируемую страницу
    		$element = $this->expectElement('param0');
    		$mode = (string) getRequest('param1');
    
                    // Оформляем данные
    		$inputData = [
    			'element'	=> $element,
    			'allowed-element-types' => [
    				'page'
    			]
    		];
                    
                    // Если передан ключевой параметр 
    		if ($mode == "do") {
                            // Сохраняем изменения страницы
    			$this->saveEditedElementData($inputData);
                            // Делаем перенаправления, в зависимости от режима кнопки "Сохранить"
    			$this->chooseRedirect();
    		}
    
                    // Устанавливаем тип данных - форма
    		$this->setDataType('form');
                    // Устанавливаем тип операции - редактирование
    		$this->setActionType('modify');
                    // Устанавливаем результаты работы метода
    		$data = $this->prepareData($inputData, 'page');
    		$this->setData($data);
    		$this->doData();
    	}
    
    	/**
    	 * Удаляет страницы модуля
    	 * @throws coreException
    	 * @throws expectElementException
    	 * @throws wrongElementTypeAdminException
    	 */
    	public function deletePages() {
                    // Получаем идентификатор страницы
    		$elements = getRequest('element');
    
    		if (!is_array($elements)) {
    			$elements = [$elements];
    		}
    
                    // Обходим массив идентификаторов
    		foreach ($elements as $elementId) {
                            // Валидируем страницу
    			$element = $this->expectElement($elementId, false, true);
    
                            // Оформляем данные страницы
    			$params = [
    				'element' => $element,
    				"allowed-element-types" => [
    					'page'
    				]
    			];
    
                            // Удаляем станицу
    			$this->deleteElement($params);
    		}
    
                    // Устанавливаем тип данных - список 
    		$this->setDataType('list');
                    // Устанавливаем тип операции - просмотр
    		$this->setActionType('view');
                    // Устанавливаем результаты работы метода
    		$data = $this->prepareData($elements, 'pages');
    		$this->setData($data);
    		$this->doData();
    	}
    
    	/**
    	 * Переключает активность страниц модуля
    	 * @throws coreException
    	 * @throws expectElementException
    	 * @throws requreMoreAdminPermissionsException
    	 * @throws wrongElementTypeAdminException
    	 */
    	public function activity() {
                    // Получаем идентификатор страницы
    		$elements = getRequest('element');
    
    		if (!is_array($elements)) {
    			$elements = [$elements];
    		}
                    
                    // Получаем флаг активности
    		$is_active = getRequest('active');
     
                    // Обходим массив идентификаторов
    		foreach ($elements as $elementId) {
                            // Валидируем страницу
    			$element = $this->expectElement($elementId, false, true);
    
                            // Оформляем данные страницы
    			$params = [
    				'element' => $element,
    				'activity' => $is_active,
    				'allowed-element-types' => [
    					'page'
    				]
    			];
    
                            // Переключаем активность
    			$this->switchActivity($params);
    			$element->commit();
    		}
    
                    // Устанавливаем тип данных - список 
    		$this->setDataType('list');
                    // Устанавливаем тип операции - просмотр
    		$this->setActionType('view');
                    // Устанавливаем результаты работы метода 
    		$data = $this->prepareData($elements, "pages");
    		$this->setData($data);
    		$this->doData();
    	}
    }
    
  4. lang.php

    В этом файле хранятся все языковые константы, используемые в клиентской части. Массив $C_LANG содержит строки, автоматически подставляемые в заголовок (title) страницы (в данном случае, это имена методов, которые могут быть вызваны напрямую: http://mysite.ru/mymodule/mymethod/), а массив $LANG_EXPORT - строки, которые могут появляться в тексте в виде макроса вида %mystring%; такие макросы будут автоматически заменены шаблонизатором на соответствующее значение из массива $LANG_EXPORT.

    Обратите внимание, что в зависимости от текущего языка, может подключаться дополнительный файл. Например, если мы находимся в английской версии и префикс у этого языка "en", то при наличии файла lang.en.php в папке модуля будет использоваться именно он.

    
    $C_LANG = [
    	'module_name' => 'Заглушка'
    ];
    
  5. i18n.php

    В этом файле хранятся все языковые константы, используемые в административной части

    Обратите внимание, что в зависимости от текущего языка, может подключаться дополнительный файл. Например, если мы находимся в английской версии административной части и префикс у этого языка "en", то при наличии файла i18n.en.php в папке модуля будет использоваться именно он.

    
    $i18n = [
    	'module-dummy'				=> 'Заглушка',
    	'header-dummy-pages'		=> 'Страницы',
    	'header-dummy-objects'		=> 'Объекты',
    	'header-dummy-config'		=> 'Настройки',
    	'header-dummy-addPage'		=> 'Создание страницы',
    	'header-dummy-editPage'		=> 'Редактирование страницы',
    	'header-dummy-addObject'	=> 'Создание объекта',
    	'header-dummy-editObject'	=> 'Редактирование объекта',
    	'group-paging'				=> 'Настройки постраничного вывода',
    	'option-pages_per_page'		=> 'Количество выводимых страниц на один лист',
    	'option-objects_per_page'	=> 'Количество выводимых объектов на один лист',
    	'label-add-page'			=> 'Создать страницу',
    	'label-add-object'			=> 'Создать объект',
    	'error-config-not-found'	=> 'Настройки не найдены',
    	'error-page-not-found'		=> 'Страница не найдена',
    ];
    

    После определения этих констант, в xslt-скине они доступны через сущности, например так &header-dummy-pages; Об этом будет рассказано подробнее в разделе Интернационализация.

  6. permissions.php

    В этом файле хранятся подключи для прав к функциям модуля.

    Основные группы прав мы задали в файле install.php, а в массиве $permissions данного файла, указывается какой метод относится к той или иной группе прав. Таким образом, если мы хотим добавить новый метод, мы должны включить его в одну из групп прав.

    
    /**
     * Группы прав на функционал модуля
     */
    $permissions = [
    	/**
    	 * Гостевые права
    	 */
    	'guest' => [
    		'page',
    		'pageslist',
    		'objectslist'
    	],
    	/**
    	 * Административный права
    	 */
    	'admin' => [
    		'pages',
    		'addpage',
    		'editpage',
    		'deletepages',
    		'activity',
    		'objects',
    		'addobject',
    		'editobject',
    		'deleteobjects'
    	]
    ];
    
  7. macros.php

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

    Пример реализации получение информации о странице и списка страниц:

    
    class DummyMacros {
    	/**
    	 * @var dummy $module
    	 */
    	public $module;
    
    		/**
    		 * Возвращает данные страницы
    		 * @param string $template имя шаблона (для tpl)
    		 * @param bool|int $pageId идентификатор страниц, если не передан - возьмет текущую страницу.
    		 * @return mixed
    		 * @throws publicAdminException
    		 */
    		public function page($template = 'default', $pageId = false) {
    				// Загружаем блоки шаблона для tpl
    			list($templateBlock) = dummy::loadTemplates('dummy/' . $template, 'block');
    
    				// Если страница не передана -  возьмем текущую
    			if (!is_numeric($pageId)) {
    				$pageId = cmsController::getInstance()->getCurrentElementId();
    			}
    
    			$umiHierarchy = umiHierarchy::getInstance();
    			$page = $umiHierarchy->getElement($pageId);
    
    				// Если страница не существует - кинем исключение
    			if (!$page instanceof iUmiHierarchyElement) {
    				throw new publicAdminException(getLabel('error-page-not-found', 'dummy'));
    			}
    
    				// Формируем нужные данные
    			$pageData = [
    				'id'	=> $pageId,
    				'link'	=> $umiHierarchy->getPathById($pageId)
    			];
    
    				// Уведомляем панель редактирования о доступной странице
    			dummy::pushEditable('dummy', 'page', $pageId);
    			  
    				// Применяем шаблон и возвращаем результат
    			return dummy::parseTemplate($templateBlock, $pageData, $pageId);
    		}
    
    		/**
    		 * Возвращает список страниц
    		 * @param string $template имя шаблона (для tpl)
    		 * @param bool|int $limit ограничение на количество, если не передано - возьмет из настроек.
    		 * @return mixed
    		 * @throws selectorException
    		 */
    		public function pagesList($template = 'default', $limit = false) {
    				// Загружаем блоки шаблона для tpl
    			list($templateBlock, $templateLine, $templateEmpty) = dummy::loadTemplates(
    				'dummy/' . $template,
    				'pages_list_block',
    				'pages_list_line',
    				'pages_list_block_empty'
    			);
    
    				// Если не передано ограничение - возьмем из настроек модуля в реестре
    			if (!is_numeric($limit)) {
    				$limit = (int) regedit::getInstance()->getVal($this->module->pagesLimitXpath);
    			}
    
    				// Получаем настройки постраничного вывода
    			$pageNumber = (int) getRequest('p');
    			$offset = $limit * $pageNumber;
    
    				// Делаем выборку
    			$pages = new selector('pages');
    			$pages->types('object-type')->name('dummy', 'page');
    			$pages->limit($offset, $limit);
    
    			$result = $pages->result();
    			$total = $pages->length();
    
    				// Если страниц нет -  применяем шаблон $templateEmpty  и возвращаем результат
    			if ($total == 0) {
    				return dummy::parseTemplate($templateEmpty, []);
    			}
    
    			$items = [];
    			$data = [];
    
    			/**
    			 * @var iUmiHierarchyElement|iUmiEntinty $page
    			 */
    				// Формируем данные каждой страницы и применяем к каждой шаблон $templateLine
    			foreach ($result as $page) {
    				$item = [];
    				$item['attribute:id'] = $page->getId();
    				$item['attribute:name'] = $page->getName();
    				$items[] = dummy::parseTemplate($templateLine, $item);
    			}
    
    				// Формируем общие данные работы макроса
    			$data['subnodes:items'] = $items;
    			$data['total'] = $total;
    
    				// Применяем общий шаблон $templateBlock и возвращаем результат
    			return dummy::parseTemplate($templateBlock, $data);
    		}
    
    	}
    
  8. customAdmin.php и customMacros.php

    Это файлы для кастомизации функционала модуля, их содержимое не меняется при обновлении системы. В customAdmin.php - добавляется административный функционал, а в customMacros.php клиентский. Эти файлы подключаются в class.php, в зависимости от режима работы системы.

    Типовое содержание customAdmin.php:

    
    class DummyCustomAdmin {
    	/**
    	 * @var dummy $module
    	 */
    	public $module;
    
    }
    

    Типовое содержание customMacros.php:

    
    class DummyCustomMacros {
    	/**
    	 * @var dummy $module
    	 */
    	public $module;
    }
    
  9. Иконки модуля

    У модуля должны быть иконки определенных размеров. Начиная с версии 2.12 в системе по умолчанию выбран скин "Modern", иконки для которого находятся в папке ~/images/cms/admin/modern/icon/. .

    Иконка должна носить имя модуля, тип иконки - прозрачный png:

    • ~/images/cms/admin/modern/icon/dummy.png — иконка 42x42 px

Устанавливаем модуль

После создания основных файлов модуля, можно попробовать его установить. Для этого необходимо зайти в конфигурацию системы ( /admin/config/modules) и в строке установки ввести classes/components/dummy/install.php. Если структура основных файлов модуля сделана корректно, модуль зарегистрируется в системе и мы увидим его в списке доступных модулей. Попробуйте перейти в наш новый модуль, должен появиться список комментариев, т.е. вызывается метод tree, который мы прописали в инталляторе, в качестве метода по умолчанию для администрирования модуля.

Теперь можно приступить к проектированию и созданию типов данных для модуля, а затем к разработке его функционала.

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

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

Создаем базовые (иерархические) типы данных

Сначала создадим базовые (иерархические) типы, чтобы корректно связать будущий тип данных с модулем. Для этого необходимо зайти в настройки модуля "Шаблоны данных" (/admin/data/config/). Вы увидите таблицу, в которой перечислены все базовые типы, на данный момент установленные в системе. В самом низу таблицы есть пустые поля, которые можно заполнить.

 

Сначала добавим базовый (иерархический) тип для страниц:

 

Название

Это обычное название, для удобства разработчика. Назовем наш тип "Страницы моего модуля"

Модуль

Модуль, который будет контролировать наш тип. Введем имя нашего модуля "dummy"

Метод

Метод, который отвечает за обработку элементов (страниц) нашего нового типа. Назовем этот метод "page"

Нажмите "Сохранить"

 

Потом добавим базовый (иерархический) тип для объектов:

 

Название

Назовем наш тип "Объекты моего модуля"

Модуль

 Введем имя нашего модуля "dummy"

Метод

 Назовем этот метод "object"

Нажмите "Сохранить"

 

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

Создаем объектные типы данных

Теперь можно перейти к созданию нужного нам типа данных. В системе уже есть типы данных, которые отвечают за страницы, отображаемые на сайте. Все они являются дочерними типами от типа данных "Раздел сайта". Зайдите в содержание типа "Раздел сайта" и увидите список всех его подтипов. Нам необходимо создать свой. Для этого нажмите на кнопку "Добавить тип данных". Откроется страница редактирования нового типа данных. Поменяем название типа на "Моя страница". Теперь необходимо связать тип данных с модулем. В выпадающем списке "Назначение типа" выберите пункт "Страницы моего модуля". Это базовый тип, который мы только что создали в настройках модуля "Шаблоны данных".

Нажмите "Сохранить". Теперь мы сможем использовать этот тип данных, как основу для создания элементов - страниц сайта.

Потом найдем в общем списке тип "Справочники", создадим к нему дочерний тип "Мой объект" и укажем ему назначение типа "Объекты моего модуля".

Завершающий этап: пишем справку

Создание справки в компонентах модулей представляет из себя немаловажную задачу. То, насколько понятно и полно будет описана работа с модулем в справке, сильно повлияет на простоту работы с вашим модулем и его компонентами, а значит и на лояльность конечного пользователя к вашему программному решению.

Несмотря на очевидную важность наличия справки, процесс её создания крайне прост и представляет собой создание обыкновенных html-документов, расположенных в файловой системе вашего сервера по следующему принципу: man/{локаль}/{модуль}/{компонент}.html, где локаль - это языковая версия административного интерфейса (может иметь значения ru или en), модуль - системное название модуля (например, для модуля Структура - это content), компонент - системное название компонента (административного метода модуля, вкладки модуля или страницы настроек модуля, например, sitetree).

Примеры расположений файлов справки существующих модулей: man/ru/emarket/orders.html - файл справки для вкладки Заказы модуля Интернет-магазин, man/ru/emarket/orders.html - файл справки для вкладки Заказы модуля Интернет-магазин, man/ru/emarket/orders_edit.html - файл справки для страницы редактирования заказа, man/ru/emarket/payment_add.html - файл справки для страницы добавления способа оплаты того же модуля, man/ru/emarket/config.html - файл справки для страницы настроек. Для административных страниц вашего компонента или модуля файл справки и, соответственно, путь до него будет свой.

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