Несколько изображений к товару средствами модуля Фотогалереи — различия между версиями
Mad grant (обсуждение | вклад) |
Mad grant (обсуждение | вклад) м (переименовал «Несколько изображений к товару средствами модуля Фотогалереии» в «[[Несколько изображений к товару средствами модуля Фот) |
||
(не показана 1 промежуточная версия этого же участника) | |||
Строка 413: | Строка 413: | ||
[[Файл:Hierarchy.png]] | [[Файл:Hierarchy.png]] | ||
− | + | ||
+ | == Дополнительно == | ||
+ | |||
+ | Также, есть и другие способы вывода нескольких картинок для товара: | ||
+ | |||
+ | <ul> | ||
+ | <li>[[Несколько_изображений_к_товару_средствами_протокола_ufs]]</li> | ||
+ | <li>[[Несколько_изображений_к_товару_средствами_дополнительных_полей]]</li> | ||
+ | </ul> | ||
+ | [[category:Модуль Каталог]][[Категория: Верстка в XSLT]][[Категория:Написание кастомных макросов]] |
Текущая версия на 15:05, 25 марта 2014
Актуально для версии 2.9.5
Содержание
Задача
Вывести на сайте несколько изображений к товару, не прибегая к созданию дополнительных папок или полей.
Решение
Задачу можно решить средствами модуля "Фотогалереи", ниже дан пример.
Вариант 1
1) Создадим в типе данных, к которому относится товар, поле типа ссылка на дерево:
2) Создадим товар с этим типом данных и заполним созданное поле в карточке товара страницами фотографий:
3) Теперь осталось это вывести, вывод в tpl есть в статье Добавление_нескольких_фотографий_к_описанию_объекта_каталога, второй вариант. В xslt же все еще проще, у нас будет примерно следующий xml документ, который нужно обработать:
<group id="5585" name="kartinki">
<title>Картинки</title>
<property id="979" name="pictures" type="symlink">
<title>Фотографии</title>
<value>
<page id="5316" parentId="5315" link="/testovyj_fotoalbom/fotografiya_1/" is-active="1" object-id="5733" type-id="74" type-guid="photoalbum-photo" update-time="1395411568" alt-name="fotografiya_1" xlink:href="upage://5316">
<basetype id="46" module="photoalbum" method="photo">Фотография</basetype>
<name>Фотография 1</name>
</page>
<page id="5317" parentId="5315" link="/testovyj_fotoalbom/photografiya_2/" is-active="1" object-id="5734" type-id="74" type-guid="photoalbum-photo" update-time="1395411993" alt-name="photografiya_2" xlink:href="upage://5317">
<basetype id="46" module="photoalbum" method="photo">Фотография</basetype>
<name>Фотография 2</name>
</page>
<page id="5318" parentId="5315" link="/testovyj_fotoalbom/fotografiya_2/" is-active="1" object-id="5735" type-id="74" type-guid="photoalbum-photo" update-time="1395411640" alt-name="fotografiya_2" xlink:href="upage://5318">
<basetype id="46" module="photoalbum" method="photo">Фотография</basetype>
<name>Фотография 3</name>
</page>
<page id="5319" parentId="5315" link="/testovyj_fotoalbom/fotografiya_4/" is-active="1" object-id="5736" type-id="74" type-guid="photoalbum-photo" update-time="1395411634" alt-name="fotografiya_4" xlink:href="upage://5319">
<basetype id="46" module="photoalbum" method="photo">Фотография</basetype>
<name>Фотография 4</name>
</page>
<page id="5320" parentId="5315" link="/testovyj_fotoalbom/fotografiya_5/" is-active="1" object-id="5737" type-id="74" type-guid="photoalbum-photo" update-time="1395411658" alt-name="fotografiya_5" xlink:href="upage://5320">
<basetype id="46" module="photoalbum" method="photo">Фотография</basetype>
<name>Фотография 5</name>
</page>
<page id="5321" parentId="5315" link="/testovyj_fotoalbom/fotografiya_6/" is-active="1" object-id="5738" type-id="74" type-guid="photoalbum-photo" update-time="1395411690" alt-name="fotografiya_6" xlink:href="upage://5321">
<basetype id="46" module="photoalbum" method="photo">Фотография</basetype>
<name>Фотография 6</name>
</page>
</value>
</property>
</group>
Обработать это дерево можно с помощью следующей конструкции:
<div style="max-width: 300; max-height: 300;">
<ul class="bxslider">
<xsl:for-each select="./page/properties/group[@name = 'kartinki']/property[@name = 'pictures']/value/page">
<li>
<xsl:apply-templates select="document(concat('udata://system/makeThumbnail/(.', document(concat('upage://', ./@id, '.photo'))//value, ')/200/auto'))"/>
</li>
</xsl:for-each>
</ul>
</div>
и шаблона, знакомого нам по статье Несколько_изображений_к_товару_средствами_протокола_ufs (bxslider мы берем оттуда же):
<xsl:template match="udata[@module = 'system' and @method = 'makeThumbnail']">
<img src="{src}"/>
</xsl:template>
Плюсы
- Легко реализовать в административном интерфейсе
- Легко вывести на сайте
Минусы
- Нельзя добавить дополнительное изображение через eip
- Для создания фотографии нужно идти в другой модуль, это очень долго
Кастомизация административного интерфейса
Попробуем решить последний минус и облегчить жизнь пользователю, то есть будет нужно:
- Дать возможность создать фотографию через карточку товара.
Пример кастомизации даем ниже.
1) Создадим в директории /styles/skins/mac/data/modules/catalog файл form.modify.custom.xsl следующего содержания:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet SYSTEM "ulang://common">
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umi="http://www.umi-cms.ru/TR/umi"
xmlns:php="http://php.net/xsl"
>
<xsl:template match="field[@type = 'symlink']" mode="form-modify">
<xsl:choose>
<xsl:when test="@name = 'pictures'">
<h3>Прикрепить фотографию:</h3>
<div class="field symlink" id="{generate-id()}" name="{@input_name}">
<label for="symlinkInput{generate-id()}">
<span class="label">
<acronym>
<xsl:apply-templates select="." mode="sys-tips" />
<strong><xsl:value-of select="@title" />:</strong>
</acronym>
<xsl:apply-templates select="." mode="required_text" />
</span>
<span id="symlinkInput{generate-id()}">
<ul id="test">
<xsl:apply-templates select="values/item" mode="symlink" />
</ul>
</span>
</label>
</div>
<h3>Добавить фотографию:</h3>
<xsl:variable name="filemanager">
<xsl:text>elfinder</xsl:text>
</xsl:variable>
<span>
<strong>Выберите изображение:</strong>
</span>
<div style="display: block;" class="field file" id="{generate-id()}" umi:input-name="photo"
umi:field-type="img_file"
umi:name="photo"
umi:folder="{@destination-folder}"
umi:file="{@relative-path}"
umi:folder-hash="{php:function('elfinder_get_hash', string(@destination-folder))}"
umi:file-hash="{php:function('elfinder_get_hash', string(@relative-path))}"
umi:lang="{/result/@interface-lang}"
umi:filemanager="{$filemanager}"
>
<label for="symlinkInput{generate-id()}">
<span id="fileControlContainer_{generate-id()}">
</span>
</label>
</div>
<xsl:variable name="gen_id" select="string(concat('fileControlContainer_', generate-id()))"/>
<xsl:variable name="sym_id" select="string(concat('symlinkInput', generate-id()))"/>
<script type="text/javascript">
$(document).ready(function(){
$('#make_element').click(function(){
$('#make_element').attr('src', "/images/cms/loading.gif");
$photo_name = $('#option_name').val();
$photo_path = $('#<xsl:value-of select="$gen_id"/> option:selected').val();
$page_id = '<xsl:value-of select="../../../@id"/>';
if($photo_name == '' || $photo_path == ''){
$('#make_element').attr('src', "/images/cms/admin/mac/table/ico_add.gif");
return jQuery.jGrowl('Выберите изображение и укажите его имя', {
'header': 'Поля не заполнены',
'life': 1500
});
}
$.ajax({
type: "POST",
url: "/udata://custom/makePhoto/.json",
dataType: "json",
data: { photo_name: $photo_name,
photo_path: $photo_path,
page_id: $page_id
}
}).done(function(json) {
$('#make_element').attr('src', "/images/cms/admin/mac/table/ico_add.gif");
$li = json.result;
$('#<xsl:value-of select="$sym_id"/> ul').append($li);
return jQuery.jGrowl('Элемент успешно добавлен, теперь можно добавить еще', {
'header': 'Элемент успешно добавлен',
'life': 1500
});
})
.fail(function() {
$('#make_element').attr('src', "/images/cms/admin/mac/table/ico_add.gif");
return jQuery.jGrowl('При добавлении элемента произошла ошибка', {
'header': 'Ошибка',
'life': 1000
});
})
});
});
</script>
<span>
<strong>Укажите имя изображения:</strong>
</span>
<span style="display: block;">
<input id="option_name" type="text" style="width: 45%;"/>
<img id="make_element" src="/images/cms/admin/mac/table/ico_add.gif"/>
</span>
</xsl:when>
<xsl:otherwise>
<div class="field symlink" id="{generate-id()}" name="{@input_name}">
<label for="symlinkInput{generate-id()}">
<span class="label">
<acronym>
<xsl:apply-templates select="." mode="sys-tips" />
<xsl:value-of select="@title" />
</acronym>
<xsl:apply-templates select="." mode="required_text" />
</span>
<span id="symlinkInput{generate-id()}">
<ul>
<xsl:apply-templates select="values/item" mode="symlink" />
</ul>
</span>
</label>
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:include href="udata://core/importSkinXsl/form.modify.xsl"/>
</xsl:stylesheet>
2) Добавим в файл /classes/modules/custom.php следующий кастомный метод:
public function makePhoto(){
$name = urldecode($_POST['photo_name']);
$name = htmlspecialchars($name);
$path = $_POST['photo_path'];
$page_id = $_POST['page_id'];
$hierarchy_col = umiHierarchy::getInstance();
$h_types_col = umiHierarchyTypesCollection::getInstance();
$h_type_id = $h_types_col->getTypeByName("photoalbum", "photo")->getId();
$photo_id = $hierarchy_col->addElement($page_id, $h_type_id, $name, translit::convert($name));
if($photo_id){
$photo = $hierarchy_col->getElement($photo_id, true, true);
$photo->setIsActive();
$photo->setValue('photo', $path);
$photo->commit();
$page = $hierarchy_col->getElement($page_id, true, true);
$value = $page->getValue('pictures');
$value[] = $photo;
$page->setValue('pictures', $value);
$page->commit();
$uri = $hierarchy_col->getPathById($photo_id);
return "<li style=\"background-color: rgb(255, 255, 254);\"><a href=\"javascript:void(0);\" class=\"button\"><img src=\"/images/cms/admin/mac/tree/symlink_delete.png\" alt=\"delete\"></a><img src=\"/images/cms/admin/mac/tree/ico_photoalbum_photo.png\"><span title=\"photoalbum photo\">$name</span><a href=\"$uri\">$uri</a></li>";
}else{
return 'Не удалось создать фотографию';
}
}
3) Теперь в карточке товара мы увидим следующее:
Не рекомендуем добавлять в эту же группу полей еще поля типа ссылка на дерево, могут быть проблемы с версткой
Вариант 2
1) Создадим в типе данных, к которому относится товар, поле типа ссылка на дерево:
Главное отличие этого варианта - возможность добавлять изображения через eip
2) Создадим товар с этим типом данных и выберем в нем фотоальбом, в котором есть фотографии:
3) Теперь осталось это вывести. В tpl для этого понадобится макрос %data getProperty()%, который выведет поле типа ссылка на дерево, а в шаблоне для вывода поля нам понадобится макрос %photoalbum album()%, для вывода картинок. В xslt же все еще проще, у нас будет примерно следующий xml документ, который нужно обработать:
<group id="5585" name="kartinki">
<title>Картинки</title>
<property id="980" name="fotoalbom" type="symlink">
<title>Фотоальбом</title>
<value>
<page id="5315" parentId="0" link="/testovyj_fotoalbom/" is-active="1" object-id="5732" type-id="73" type-guid="photoalbum-album" update-time="1395411705" alt-name="testovyj_fotoalbom" xlink:href="upage://5315">
<basetype id="45" module="photoalbum" method="album">Фотоальбом</basetype>
<name>Тестовый фотоальбом 1</name>
</page>
</value>
</property>
</group>
Обработать это дерево можно с помощью следующего вызова (снова используется bxslider):
<xsl:apply-templates select="document(concat('udata://photoalbum/album/', ./page/properties/group[@name = 'kartinki']/property[@name = 'fotoalbom']/value/page/@id))"/>
и двух темлпейтов:
<xsl:template match="udata[@module = 'photoalbum' and @method = 'album']">
<div style="max-width: 300; max-height: 300;">
<ul class="bxslider">
<xsl:for-each select="./items/item">
<li>
<xsl:apply-templates select="document(concat('udata://system/makeThumbnail/(.', document(concat('upage://', ./@id, '.photo'))//value, ')/200/auto'))"/>
</li>
</xsl:for-each>
</ul>
</div>
</xsl:template>
<xsl:template match="udata[@module = 'system' and @method = 'makeThumbnail']">
<img src="{src}"/>
</xsl:template>
Плюсы
- Легко реализовать в административном интерфейсе
- Фотографии можно добавлять в eip
- Фотографии можно загружать массово через модуль "Фотогалереи"
Минусы
- Модуль "Фотогалереи" будет забит множеством альбомов для каждого товара
- Для создания фотоальбома нужно идти в другой модуль, это очень долго
Добавление обработчика события
Попробуем решить последний минус и облегчить жизнь пользователю, то есть будет нужно:
- Автоматически генерировать альбом при создании товара и привязывать его к нему
Пример кастомизации даем ниже.
Для создания фотоальбома мы воспользуемся событийной моделью UMI.CMS и напишем обработчик для события systemCreateElement.
1) Добавим следующий кастомный метод в файл /classes/modules/catalog/__custom.php:
public function mkAlbum(iUmiEventPoint $event){
if($event->getMode() === "after") {
$page = $event->getRef("element");
$page_type = $page->getHierarchyType();
if ($page_type->getName() == 'catalog' && $page_type->getExt() == 'object'){
$page_name = $page->getName();
$page_id = $page->getId();
$hierarchy_col = umiHierarchy::getInstance();
$h_types_col = umiHierarchyTypesCollection::getInstance();
$h_type_id = $h_types_col->getTypeByName("photoalbum", "album")->getId();
$album_id = $hierarchy_col->addElement($page_id, $h_type_id, 'Альбом для товара ' . $page_name, translit::convert('Альбом для товара ' . $page_name));
$album = $hierarchy_col->getElement($album_id, true, true);
$album->setIsActive();
$album->commit();
$page->setValue('fotoalbom', $album_id);
$page->commit();
}
}
}
При желании, Вы можете написать аналогичные обработчики и для других событий, например на события добавления страницы через импорт.
2) В той же директории создадим файл custom_events.php следующего содержания:
<?php
new umiEventListener('systemCreateElement', 'catalog', 'mkAlbum');
?>
и файл permissions.custom.php следующего содержания:
<?php
$permissions = array(
'tree' => array(),
'view' => array('mkAlbum')
);
?>
3) Теперь при создании товара через административную панель будут происходить следующие действия:
- Будет создаваться фотоальбом с именем "Альбом для товара <имя_товара>"
- Альбом будет добавлять в страницу товара, в поле типа ссылка на дерево со строковым идентификатором 'fotoalbom'
- Добавленный фотоальбом по иерархии будет дочерним к странице товара
Дополнительно
Также, есть и другие способы вывода нескольких картинок для товара: