Макрос для поиска по названию страниц (упрощенный search search_do())

В данной статье мы рассмотрим пример макроса для поиска по сайту. У umi уже существует макросы для поиска: catalog search() — выводит фильтр по товарам и search search_do() — выводит результаты поиска по сайту. Наш макрос будет представлять из себя упрощенный вариант search search_do(). Он будет искать только по названию страниц, а также может быть ограничен определенным разделом или типом данных.

Мы будем демонстрировать пример, который работает с новой системой хранения шаблонов и новой системой расширения функционала. Все работы будут проводиться на демо сайте "demodizzy".

  1. Создадим папку и необходимые файлы для расширения функционала модуля search.
    файл с макросом: /templates/demodizzy/classes/modules/search/class.php
    <?php class search_custom extends def_module {
        //TODO: Write here your own macroses
         
        public function simple_search_do($template = "default", $search_string = "", $per_page = 0, $path = NULL, $type_id = NULL, $type_module_name = NULL, $type_method_name = NULL) {
            list(
                $template_block, $template_line, $template_empty_result, $template_line_quant
            ) = self::loadTemplates("search/".$template,
                "search_block", "search_block_line", "search_empty_result", "search_block_line_quant"
            );
            // поисковая фраза :
            if (!$search_string) $search_string = (string) getRequest('search_string');
     
            $block_arr = Array();
            $block_arr['last_search_string'] = $search_string;
     
            $search_string = urldecode($search_string);
            $search_string = htmlspecialchars($search_string);
            $search_string = str_replace(".", " ", $search_string);
            $search_string = trim($search_string, " \t\r\n%");
            $search_string = str_replace(array('"', "'"), "", $search_string);
                 
            if (!$search_string) return $this->insert_form($template);
     
            $lines = Array();
             
            $p = (int) getRequest('p');
            if (!$per_page) $per_page = intval(getRequest('per_page'));
            if (!$per_page) $per_page = $this->per_page;
            $i = $per_page * $p;
             
            $pages = new selector('pages');
             
            // если запрошен поиск только по определенному типу
            if($type_id){
                if(!($type = umiObjectTypesCollection::getInstance()->getType($type_id)))  trigger_error("Failed to load type", E_USER_WARNING);
                $pages->types('object-type')->id($type_id);
            }elseif($type_module_name && $type_method_name){
                $hierarchy_type_id = umiHierarchyTypesCollection::getInstance()->getTypeByName($type_module_name, $type_method_name)->getId();
                if($hierarchy_type_id)  $pages->types('hierarchy-type')->name($type_module_name, $type_method_name);
            }
             
            // если запрошен поиск только по определенным подразделам
            $arr_search_by_rels = array();
            if (!$path) $path = (string) getRequest('search_branches');
            $path = trim(rawurldecode($path));
            if (strlen($path)) {
                $arr_parents = preg_split("/[\s,]+/", $path);
                foreach ($arr_parents as $parent_page) {
                    $parent_page_id = $this->analyzeRequiredPath($parent_page);
                    $pages->where('hierarchy')->page($parent_page_id)->childs(1000);
                }
            }  
            $pages->where('name')->like('%'.$search_string.'%');
            $pages->limit($i, $per_page); // offset,limit
            $total = $pages->length;
     
            foreach($pages as $element) {
                $line_arr = Array();
                 
                $element_id = $element->id;
                $line_arr['void:num'] = ++$i;
                $line_arr['attribute:id'] = $element_id;
                $line_arr['attribute:name'] = $element->getName();
                $line_arr['attribute:link'] = umiHierarchy::getInstance()->getPathById($element_id);
                $line_arr['xlink:href'] = "upage://" . $element_id;
                $lines[] = def_module::parseTemplate($template_line, $line_arr, $element_id);
     
                $this->pushEditable(false, false, $element_id);
                umiHierarchy::getInstance()->unloadElement($element_id);
            }
            $block_arr['subnodes:items'] = $block_arr['void:lines'] = $lines;
            $block_arr['total'] = $total;
            $block_arr['per_page'] = $per_page;
     
            return def_module::parseTemplate(($total > 0 ? $template_block : $template_empty_result), $block_arr);
        }
    };
    ?>
    файл с макросом: /templates/demodizzy/classes/modules/search/permissions.php
    <?php
    	$permissions = Array(
    		'search' => Array('simple_search_do')
    	);
    ?>
  2. Подключим новый шаблон для обработки данного макроса.
    Для этого добавим файл /templates/demodizzy/xslt/modules/search/simple-search-result.xsl  (не забываем его подключить в файле /templates/demodizzy/xslt/modules/search/common.xsl)
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE xsl:stylesheet SYSTEM     "ulang://i18n/constants.dtd:file">
    
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umi="http://www.umi-cms.ru/TR/umi">
        <xsl:template match="/result[@method = 'simple_search_do']">
            <xsl:apply-templates select="document('udata://search/simple_search_do')" />
        </xsl:template>
        
        <xsl:template match="udata[@method = 'simple_search_do']">
            <p>
    		<strong>
    			<xsl:text>&search-founded-left; "</xsl:text>
    			<xsl:value-of select="$search_string" />
    			<xsl:text>" &search-founded-nothing;.</xsl:text>
    		</strong>
    	</p>
        </xsl:template>
        
        <xsl:template match="udata[@method = 'simple_search_do' and items/item]">
    	<p>
    		<strong>
    			<xsl:text>&search-founded-left; "</xsl:text>
    			<xsl:value-of select="$search_string" />
    			<xsl:text>" &search-founded-right;: </xsl:text>
    			<xsl:value-of select="total" />
    			<xsl:text>.</xsl:text>
    		</strong>
    	</p>
    
    	<ul class="search">
    		<xsl:apply-templates select="items/item" mode="search-result" />
    	</ul>
    	<xsl:apply-templates select="total" />
        </xsl:template>
        
        <xsl:template match="item" mode="search-result">
    	<li>
    		<span>
    			<xsl:value-of select="($p*../../per_page) + position()" />.
    		</span>
    		<a href="{@link}">
    			<xsl:value-of select="@name" />
    		</a>
    	</li>
        </xsl:template>
    </xsl:stylesheet>
  3. Вставляем в нужное место сайта форму, для вызова нашего макроса. У формы можно указать необязательный параметр search_branches, соответственно в нем можно указать id или url разделов, внутри которых вы хотели бы осуществлять поиск (значения разделяются запятой).
    <form class="search" action="/search/simple_search_do/" method="get">
    	<input type="text" value="&search-default-text;" name="search_string" class="textinputs" onblur="javascript: if(this.value == '') this.value = '&search-default-text;';" onfocus="javascript: if(this.value == '&search-default-text;') this.value = '';"  x-webkit-speech="" speech="" />
    	<input type="hidden" name="search_branches" value="51,49" />
    	<input type="submit" value="&search-default-text;" />
    </form>






comments powered by HyperComments