Инфо Правильные хлебные крошки Google Breadcrumps для Prestashop 1.6 и немного про Schema.org > Products

Тема в разделе "PrestaShop", создана пользователем trace, 27 июл 2017.

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

(Не актуальные темы) Каталоги:Модули PrestaShop 1.7Модули PrestaShop 1.5 - 1.6Шаблоны PrestaShop 1.7Шаблоны PrestaShop 1.5 - 1.6
(Не актуальные темы) Поиск / Запросы:Модули PrestaShop 1.7Модули PrestaShop 1.5 - 1.6Шаблоны PrestaShop 1.7Шаблоны PrestaShop 1.5 - 1.6
Полезная информация:Поддержка и помощь c PrestaShopУбираем ПрестаТраст, стучалки и прочую рекламуСовместные покупки модулей и шаблоновПеревод Prestashop и модулей
Модераторы: trace
  1. trace

    trace Prestashop

    Moderator
    Регистр.:
    4 ноя 2013
    Сообщения:
    321
    Симпатии:
    579
    Хлебные крошки с микроразметкой Schema.org

    Обновлено:
    - display:none изменен на meta
    - position теперь начинается с 1
    - путь хлебных крошек для товара теперь привязан к категории по умолчанию


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

    1. В файле ваш_сайт/themes/ваша_тема/breadcrumb.tpl
    Заменяем:
    PHP:
    <!-- Breadcrumb -->
    {if isset(
    $smarty.capture.path)}{assign var='path' value=$smarty.capture.path}{/if}
    <
    div class="breadcrumb clearfix">
        <
    class="home" href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{l s='Return to Home'}"><class="icon-home"></i></a>
        {if isset(
    $path) AND $path}
            <
    span class="navigation-pipe"{if isset($category) && isset($category->id_category) && $category->id_category == (int)Configuration::get('PS_ROOT_CATEGORY')} style="display:none;"{/if}>{$navigationPipe|escape:'html':'UTF-8'}</span>
            {if 
    $path|strpos:'span' !== false}
                <
    span class="navigation_page">{$path|@replace:'<a ''<span itemscope itemtype="http://data-vocabulary.org/Breadcrumb"><a itemprop="url" '|@replace:'data-gg="">''><span itemprop="title">'|@replace:'</a>''</span></a></span>'}</span>
            {else}
                {
    $path}
            {/if}
        {/if}
    </
    div>
    на:
    PHP:
    <!-- Breadcrumb -->
    {if isset(
    $smarty.capture.path)}{assign var='path' value=$smarty.capture.path}{/if}
    <
    div class="breadcrumb" {if $page_name == 'product' or $page_name == 'category' or $page_name == 'cms'}itemscope itemtype="http://schema.org/BreadcrumbList"{/if}>
    <!--    <
    div class="container"  > -->
            <!--<
    meta itemprop="name" content="{$meta_title|escape:'html':'UTF-8'}"/>-->
            <
    span {if $page_name == 'product' or $page_name == 'category' or $page_name == 'cms'}itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ListItem"{/if}><meta itemprop="position" content="1"><class="home" itemprop="item" href="{if isset($force_ssl) && $force_ssl}{$base_dir_ssl}{else}{$base_dir}{/if}" title="{l s='Return to Home'}"><meta itemprop="name" content="{l s='Home'}" /><class="icon-home"></i></a></span>
        {if isset(
    $path) AND $path}
            <
    span  class="navigation-pipe"  {if isset($category) && isset($category->id_category) && $category->id_category == (int)Configuration::get('PS_ROOT_CATEGORY')} style="display:none;"{/if}>{$navigationPipe|escape:'html':'UTF-8'}</span>
            {if 
    $page_name == 'product' or $page_name == 'category' or $page_name == 'cms'}
                {if 
    $path|strpos:'span' !== false}
                    <
    span  class="navigation_page" >
                    {
    $path|@replace:'<a ''<span > <span >
                        <a itemprop="item" '
    |@replace:'data-gg="">''>
                        <span >'
    |@replace:'</a>''</a></span></span>'}</span>
                {else}
                    <
    span itemprop="itemListElement" class="item-breadcrumb" itemscope="" itemtype="http://schema.org/ListItem"><meta itemprop="position" content="1"><meta itemprop="item" content="{if isset($force_ssl) && $force_ssl}https://{$smarty.server.HTTP_HOST}{$smarty.server.REQUEST_URI}{else}http://{$smarty.server.HTTP_HOST}{$smarty.server.REQUEST_URI}{/if}" /><meta itemprop="name" content="{$path}/><span class="item-breadalone">{$path}</span></span>
                {/if}
            {else}
                {if 
    $path|strpos:'span' !== false}
                    <
    span  class="navigation_page" >
                    {
    $path|@replace:'<a ''<span > <span >
                        <a '
    |@replace:'data-gg="">''>
                        <span >'
    |@replace:'</a>''</a></span></span>'}</span>
                {else}
                    <
    span class="item-breadalone">{$path}</span>
                {/if}
            {/if}
        {/if}
    </
    div>
    2. Создаем файл Tools.php в кодировке UTF-8 без BOM (можно сделать, например, с помощью Notepad++ ) с нижеследующим содержанием и закидываем его в папку ваш_сайт/override/classes/
    PHP:
    <?php

    class Tools extends ToolsCore{
    public static function 
    getPath($id_category$path ''$link_on_the_item false$category_type 'products'Context $context null)
        {
            if (!
    $context)
                
    $context Context::getContext();
            
    $id_category = (int)$id_category;
            if (
    $id_category == 1)
                return 
    '<span class="navigation_end">'.$path.'</span>';
            
    $pipe Configuration::get('PS_NAVIGATION_PIPE');
            if (empty(
    $pipe))
                
    $pipe '>';
            
    $full_path '';
            if (
    $category_type === 'products')
            {
                
    $interval Category::getInterval($id_category);
                
    $id_root_category $context->shop->getCategory();
                
    $interval_root Category::getInterval($id_root_category);
                if (
    $interval)
                {
                    
    $sql 'SELECT c.id_category, cl.name, cl.link_rewrite, cl.meta_title
                            FROM '
    ._DB_PREFIX_.'category c
                            LEFT JOIN '
    ._DB_PREFIX_.'category_lang cl ON (cl.id_category = c.id_category'.Shop::addSqlRestrictionOnLang('cl').')
                            '
    .Shop::addSqlAssociation('category''c').'
                            WHERE c.nleft <= '
    .$interval['nleft'].'
                                AND c.nright >= '
    .$interval['nright'].'
                                AND c.nleft >= '
    .$interval_root['nleft'].'
                                AND c.nright <= '
    .$interval_root['nright'].'
                                AND cl.id_lang = '
    .(int)$context->language->id.'
                                AND c.active = 1
                                AND c.level_depth > '
    .(int)$interval_root['level_depth'].'
                            ORDER BY c.level_depth ASC'
    ;
                    
    $categories Db::getInstance()->executeS($sql);
                    
    $n 1;
                    
    $n_categories count($categories);
                    foreach (
    $categories as $key => $category)
                    {
                        
    $key $key+2;
                        
    $full_path .='<span itemprop="itemListElement" class="item-breadcrumb" itemscope="" itemtype="http://schema.org/ListItem" ><meta itemprop="position" content="'.$key.'">'. (($n $n_categories || $link_on_the_item) ? '<a itemprop="url" href="'.Tools::safeOutput($context->link->getCategoryLink((int)$category['id_category'], $category['link_rewrite'])).'" title="'.htmlentities($category['name'], ENT_NOQUOTES'UTF-8').'">' '<meta itemprop="url" content="'.Tools::safeOutput($context->link->getCategoryLink((int)$category['id_category'], $category['link_rewrite'])).'" title="'.htmlentities($category['name'], ENT_NOQUOTES'UTF-8').'" />').'<meta itemprop="name" content="'.htmlentities($category['name'], ENT_NOQUOTES'UTF-8').'" />'.
                        
    htmlentities($category['name'], ENT_NOQUOTES'UTF-8').
                        ((
    $n $n_categories || $link_on_the_item) ? '</a>' '').
                        ((
    $n++ != $n_categories || !empty($path)) ? '<span class="navigation-pipe">'.$pipe.'</span>' '').'</span>';
                    }
                    return 
    $full_path.$path;
                }
            }
            else if (
    $category_type === 'CMS')
            {
                
    $category = new CMSCategory($id_category$context->language->id);
                if (!
    Validate::isLoadedObject($category))
                    die(
    Tools::displayError());
                
    $category_link $context->link->getCMSCategoryLink($category);
                if (
    $path != $category->name)
                    
    $full_path .= '<a href="'.Tools::safeOutput($category_link).'">'.htmlentities($category->nameENT_NOQUOTES'UTF-8').'</a><span class="navigation-pipe">'.$pipe.'</span>'.$path;
                else
                    
    $full_path = ($link_on_the_item '<a href="'.Tools::safeOutput($category_link).'">' '').htmlentities($pathENT_NOQUOTES'UTF-8').($link_on_the_item '</a>' '');
                return 
    Tools::getPath($category->id_parent$full_path$link_on_the_item$category_type);
            }
        }
    }
    3. Создаем файл ProductController.php в кодировке UTF-8 без BOM с нижеследующим содержанием и закидываем его в папку ваш_сайт/override/controllers/front/
    PHP:
    <?php

    class ProductController extends ProductControllerCore
    {

        protected function 
    assignCategory()
        {
            
    // Assign category to the template
            
    if ($this->category !== false && Validate::isLoadedObject($this->category) && $this->category->inShop() && $this->category->isAssociatedToShop()) {
                
    $this->category = new Category((int)$this->product->id_category_default, (int)$this->context->language->id);
                
    $path Tools::getPath($this->product->id_category_default$this->product->nametrue);
            } elseif (
    Category::inShopStatic($this->product->id_category_default$this->context->shop)) {
                
    $this->category = new Category((int)$this->product->id_category_default, (int)$this->context->language->id);
                if (
    Validate::isLoadedObject($this->category) && $this->category->active && $this->category->isAssociatedToShop()) {
                    
    $path Tools::getPath((int)$this->product->id_category_default$this->product->name);
                }
            }
            if (!isset(
    $path) || !$path) {
                
    $this->category = new Category((int)$this->product->id_category_default, (int)$this->context->language->id);
                
    $path Tools::getPath($this->product->id_category_default$this->product->nametrue);
            }

            
    $sub_categories = array();
            if (
    Validate::isLoadedObject($this->category)) {
                
    $sub_categories $this->category->getSubCategories($this->context->language->idtrue);

                
    // various assignements before Hook::exec
                
    $this->context->smarty->assign(array(
                    
    'path' => $path,
                    
    'category' => $this->category,
                    
    'subCategories' => $sub_categories,
                    
    'id_category_current' => (int)$this->category->id,
                    
    'id_category_parent' => (int)$this->category->id_parent,
                    
    'return_category_name' => Tools::safeOutput($this->category->getFieldByLang('name')),
                    
    'categories' => Category::getHomeCategories($this->context->language->idtrue, (int)$this->context->shop->id)
                ));
            }
            
    $this->context->smarty->assign(array('HOOK_PRODUCT_FOOTER' => Hook::exec('displayFooterProduct', array('product' => $this->product'category' => $this->category))));
        }

    }
    4. Удаляем файл class_index.php из папки ваш_сайт/cache, и на всякий случай чистим кэш в "Расширенные параметры > Производительность".


    Тема на форуме Prestashop:
    https://www.prestashop.com/forums/t...adcrumb-schemaorg-microdate-for-prestashop-16
     
    Последнее редактирование: 12 ноя 2017
    vit2010, Jame, _sashok и 4 другим нравится это.
  2. radeon6

    radeon6 Создатель

    Регистр.:
    21 авг 2014
    Сообщения:
    15
    Симпатии:
    4
    В том же тесте разметки - "1 200,00 руб (Свойство 1 200,00 руб не является допустимым значением цены. Подробнее о свойстве price стандарта schema.org...)".
    Судя по всему виной формат валюты, в Локализация/валюты выбора соответствующего формата для schema.org нет. Где поменять формат валюты?

    PS
    В админке формат в выпадающем списке меняется в AdminCurrenciesController.php
     
    Последнее редактирование: 2 авг 2017
  3. trace

    trace Prestashop

    Moderator
    Регистр.:
    4 ноя 2013
    Сообщения:
    321
    Симпатии:
    579
    А причем здесь "хлебные крошки"? Ладно подскажу.

    themes/ваша_тема/product.tpl
    PHP:
                <span itemprop="price" id="our_price_display" class="price">{convertPrice price=$productPrice}</span>
                    <
    meta itemprop="priceCurrency" content="{$currency->iso_code}/>
    меняем на:
    PHP:
               <span id="our_price_display" class="price">{convertPrice price=$productPrice}</span>
                   <
    meta itemprop="price" content="{$productPrice}/>
                   <
    meta itemprop="priceCurrency" content="{$currency->iso_code}/>
    themes/ваша_тема/product-list.tpl
    PHP:
                   <span itemprop="price" class="price product-price" {if $product.specific_prices.reduction_type == 'percentage'}style="color:#f13340;"{/if}>
                           {if !
    $priceDisplay}{convertPrice price=$product.price}{else}{convertPrice price=$product.price_tax_exc}{/if}
                   </
    span>
                   <
    meta itemprop="priceCurrency" content="{$currency->iso_code}/>
    меняем на:
    PHP:
                   <span class="price product-price" {if $product.specific_prices.reduction_type == 'percentage'}style="color:#f13340;"{/if}>
                           {if !
    $priceDisplay}{convertPrice price=$product.price}{else}{convertPrice price=$product.price_tax_exc}{/if}
                   </
    span>
                   <
    meta itemprop="price" content="{$product.price}/>
                   <
    meta itemprop="priceCurrency" content="{$currency->iso_code}/>
     
    Последнее редактирование: 26 авг 2017
    vit2010, evgenij.sobolev и _sashok нравится это.
  4. radeon6

    radeon6 Создатель

    Регистр.:
    21 авг 2014
    Сообщения:
    15
    Симпатии:
    4
    Непричём, сделал тест разметки вашего варианта "крошек", а в разметке цены предупреждение выше мною процитированное. Вот и спросил как поправить.
    Мне требуется поменять формат цены, в tpl шаблонах у меня всё нормально. Сейчас один из стандартных форматов престы, выводит цену как 0 000,00X, нужно поменять на 0000.00X.
     
  5. trace

    trace Prestashop

    Moderator
    Регистр.:
    4 ноя 2013
    Сообщения:
    321
    Симпатии:
    579
    Что насчет микроразметки, я уже написал выше. Google кушет, всё работает.

    В вашем случае чтобы изменить формат валюты для отображения в магазине надо:

    Зайти в "Локализация > Валюты > Правка > Формат валюты".
    Там же можно убрать десятичные.

    Если вот прям так надо (0000.00X), то создаем файл (не через обычный блокнот, а например через Notepad++ (чтобы кодировка была UTF-8 без BOM)) с названием Tools.php и содержимым:
    PHP:
    <?php

    class Tools extends ToolsCore
    {

        public static function 
    displayPrice($price$currency null$no_utf8 falseContext $context null)
        {
            if (!
    is_numeric($price))
                return 
    $price;
            if (!
    $context)
                
    $context Context::getContext();
            if (
    $currency === null)
                
    $currency $context->currency;
            
    // if you modified this function, don't forget to modify the Javascript function formatCurrency (in tools.js)
            
    elseif (is_int($currency))
                
    $currency Currency::getCurrencyInstance((int)$currency);

            if (
    is_array($currency))
            {
                
    $c_char $currency['sign'];
                
    $c_format $currency['format'];
                
    $c_decimals = (int)$currency['decimals'] * _PS_PRICE_DISPLAY_PRECISION_;
                
    $c_blank $currency['blank'];
            }
            elseif (
    is_object($currency))
            {
                
    $c_char $currency->sign;
                
    $c_format $currency->format;
                
    $c_decimals = (int)$currency->decimals _PS_PRICE_DISPLAY_PRECISION_;
                
    $c_blank $currency->blank;
            }
            else
                return 
    false;

            
    $blank = ($c_blank ' ' '');
            
    $ret 0;
            if ((
    $is_negative = ($price 0)))
                
    $price *= -1;
            
    $price Tools::ps_round($price$c_decimals);

            
    /*
            * If the language is RTL and the selected currency format contains spaces as thousands separator
            * then the number will be printed in reverse since the space is interpreted as separating words.
            * To avoid this we replace the currency format containing a space with the one containing a comma (,) as thousand
            * separator when the language is RTL.
            *
            * TODO: This is not ideal, a currency format should probably be tied to a language, not to a currency.
            */
            
    if (($c_format == 2) && ($context->language->is_rtl == 1))
                
    $c_format 4;

            switch (
    $c_format)
            {
                
    /* X 0,000.00 */
                
    case 1:
                    
    $ret $c_char.$blank.number_format($price$c_decimals'.'',');
                    break;
                
    /* 0000.00X */
                
    case 2:
                    
    $ret number_format($price$c_decimals'.''').$blank.$c_char;
                    break;
                
    /* X 0.000,00 */
                
    case 3:
                    
    $ret $c_char.$blank.number_format($price$c_decimals',''.');
                    break;
                
    /* 0,000.00 X */
                
    case 4:
                    
    $ret number_format($price$c_decimals'.'',').$blank.$c_char;
                    break;
                
    /* X 0'000.00  Added for the switzerland currency */
                
    case 5:
                    
    $ret number_format($price$c_decimals'.'"'").$blank.$c_char;
                    break;
            }
            if (
    $is_negative)
                
    $ret '-'.$ret;
            if (
    $no_utf8)
                return 
    str_replace('€'chr(128), $ret);
            return 
    $ret;
        }
    }
    Закидываем файл в папку .../override/classes/

    Удаляем файл class_index.php из папки .../cache/

    Соответственно, всё в тех же настройках "Локализация > Валюты > Правка > Формат валюты" выбираем 2-й пункт и включаем десятичные, если нужно. Всё готово.
     
    Последнее редактирование: 4 авг 2017
    evgenij.sobolev и radeon6 нравится это.
  6. radeon6

    radeon6 Создатель

    Регистр.:
    21 авг 2014
    Сообщения:
    15
    Симпатии:
    4
    Это работает, спасибо.
    А почему вы всё делаете через "override/", какой в этом смысл?
     
  7. trace

    trace Prestashop

    Moderator
    Регистр.:
    4 ноя 2013
    Сообщения:
    321
    Симпатии:
    579
    Оверрайд - это перезаписывание части кода без изменения оригинальных файлов.
    Соответственно, вы сможете обновлять движок через модуль обновления без проблем.
    Если делать изменения в оригинальных файлах движка, то при обновлении они будут заменены новыми и ваши изменения удалятся.
     
    _sashok, evgenij.sobolev и radeon6 нравится это.
  8. evgenij.sobolev

    evgenij.sobolev

    Регистр.:
    8 дек 2015
    Сообщения:
    214
    Симпатии:
    215
    Для использвоания вашего решения, надо заменить эти файлы на ваши версии:
    /theme/your_theme/breadcrumb.tpl
    /override/classes/Tools.php
    Верно?
     
  9. trace

    trace Prestashop

    Moderator
    Регистр.:
    4 ноя 2013
    Сообщения:
    321
    Симпатии:
    579
    Верно. Потом удалить файл class_index.php из папки .../cache/. Однако смотрите стили и классы в tpl-файле, возможно в вашей теме собьется оформление.

    Потом только не забудьте прописать категории по умолчанию у товаров. Чтобы была конечная, а не главная. Если у товара несколько категорий, то по умолчанию выбирайте на шаг назад или самую приоритетную.
     
    Последнее редактирование: 6 авг 2017
    zen1 и evgenij.sobolev нравится это.
  10. fortuner

    fortuner Нарушитель

    Регистр.:
    26 июн 2012
    Сообщения:
    558
    Симпатии:
    897
    А что было не так со стандартными хлебными крошками?