Product tabs like in 1.5

In this guide i want to show you how to change way of displaying product tabs in prestashop 1.6 default-bootstrap template. As you probably know prestashop 1.6 displays product tabs as a wide horizontal bars, these wide bards in fact aren't a real tabs like they were displayed in prestashop 1.5. In this guide i want to show you how to change them to real tabs with responsiveness.

 

product page tabs prestashop 1.6

 

Tabs modification

In this case we have to modify two things. First the most important change is related to template file which displays product details. It's a product.tpl file located in your theme directory. Second thing - is css style definition for these tabs. Css definition for this section is a part of global.css file located in theme directory, in css subdirectory.

 

Product.tpl file modification - download modified file for PrestaShop 1.6.x

okay, so as i said above we have to modify product.tpl file, you can find it here: /themes/default-bootstrap/product.tpl. Open it, and search for code that i pasted below:

{if isset($features) && $features}
			<!-- Data sheet -->
			<section class="page-product-box">
				<h3 class="page-product-heading">{l s='Data sheet'}</h3>
				<table class="table-data-sheet">			
					{foreach from=$features item=feature}
					<tr class="{cycle values="odd,even"}">
						{if isset($feature.value)}			    
						<td>{$feature.name|escape:'html':'UTF-8'}</td>
						<td>{$feature.value|escape:'html':'UTF-8'}</td>
						{/if}
					</tr>
					{/foreach}
				</table>
			</section>
			<!--end Data sheet -->
		{/if}
		{if $product->description}
			<!-- More info -->
			<section class="page-product-box">
				<h3 class="page-product-heading">{l s='More info'}</h3>{/if}
				{if isset($product) && $product->description}
					<!-- full description -->
					<div  class="rte">{$product->description}</div>
			</section>
			<!--end  More info -->
		{/if}
		<!--HOOK_PRODUCT_TAB -->
		<section class="page-product-box">
			{$HOOK_PRODUCT_TAB}
			{if isset($HOOK_PRODUCT_TAB_CONTENT) && $HOOK_PRODUCT_TAB_CONTENT}{$HOOK_PRODUCT_TAB_CONTENT}{/if}
		</section>
		<!--end HOOK_PRODUCT_TAB -->
		{if isset($accessories) && $accessories}
			<!--Accessories -->
			<section class="page-product-box">
				<h3 class="page-product-heading">{l s='Accessories'}</h3>
				<div class="block products_block accessories-block clearfix">
					<div class="block_content">
						<ul id="bxslider" class="bxslider clearfix">
							{foreach from=$accessories item=accessory name=accessories_list}
								{if ($accessory.allow_oosp || $accessory.quantity_all_versions > 0 || $accessory.quantity > 0) && $accessory.available_for_order && !isset($restricted_country_mode)}
									{assign var='accessoryLink' value=$link->getProductLink($accessory.id_product, $accessory.link_rewrite, $accessory.category)}
									<li class="item product-box ajax_block_product{if $smarty.foreach.accessories_list.first} first_item{elseif $smarty.foreach.accessories_list.last} last_item{else} item{/if} product_accessories_description">
										<div class="product_desc">
											<a href="{$accessoryLink|escape:'html':'UTF-8'}" title="{$accessory.legend|escape:'html':'UTF-8'}" class="product-image product_image">
												<img class="lazyOwl" src="{$link->getImageLink($accessory.link_rewrite, $accessory.id_image, 'home_default')|escape:'html':'UTF-8'}" alt="{$accessory.legend|escape:'html':'UTF-8'}" width="{$homeSize.width}" height="{$homeSize.height}"/>
											</a>
											<div class="block_description">
												<a href="{$accessoryLink|escape:'html':'UTF-8'}" title="{l s='More'}" class="product_description">
													{$accessory.description_short|strip_tags|truncate:25:'...'}
												</a>
											</div>
										</div>
										<div class="s_title_block">
											<h5 class="product-name">
												<a href="{$accessoryLink|escape:'html':'UTF-8'}">
													{$accessory.name|truncate:20:'...':true|escape:'html':'UTF-8'}
												</a>
											</h5>
											{if $accessory.show_price && !isset($restricted_country_mode) && !$PS_CATALOG_MODE}
											<span class="price">
												{if $priceDisplay != 1}
												{displayWtPrice p=$accessory.price}{else}{displayWtPrice p=$accessory.price_tax_exc}
												{/if}
											</span>
											{/if}
										</div>
										<div class="clearfix" style="margin-top:5px">
											{if !$PS_CATALOG_MODE && ($accessory.allow_oosp || $accessory.quantity > 0)}
												<div class="no-print">
													<a class="exclusive button ajax_add_to_cart_button" href="{$link->getPageLink('cart', true, NULL, "qty=1&amp;id_product={$accessory.id_product|intval}&amp;token={$static_token}&amp;add")|escape:'html':'UTF-8'}" data-id-product="{$accessory.id_product|intval}" title="{l s='Add to cart'}">
														<span>{l s='Add to cart'}</span>
													</a>
												</div>
											{/if}
										</div>
									</li>
								{/if}
							{/foreach}
						</ul>
					</div>
				</div>	
			</section>
			<!--end Accessories -->
		{/if}
		{if isset($HOOK_PRODUCT_FOOTER) && $HOOK_PRODUCT_FOOTER}{$HOOK_PRODUCT_FOOTER}{/if}
		<!-- description & features -->
		{if (isset($product) && $product->description) || (isset($features) && $features) || (isset($accessories) && $accessories) || (isset($HOOK_PRODUCT_TAB) && $HOOK_PRODUCT_TAB) || (isset($attachments) && $attachments) || isset($product) && $product->customizable}
			{if isset($attachments) && $attachments}
			<!--Download -->
			<section class="page-product-box">
				<h3 class="page-product-heading">{l s='Download'}</h3>
				{foreach from=$attachments item=attachment name=attachements}
					{if $smarty.foreach.attachements.iteration %3 == 1}<div class="row">{/if}
						<div class="col-lg-4">
							<h4><a href="{$link->getPageLink('attachment', true, NULL, "id_attachment={$attachment.id_attachment}")|escape:'html':'UTF-8'}">{$attachment.name|escape:'html':'UTF-8'}</a></h4>
							<p class="text-muted">{$attachment.description|escape:'html':'UTF-8'}</p>
							<a class="btn btn-default btn-block" href="{$link->getPageLink('attachment', true, NULL, "id_attachment={$attachment.id_attachment}")|escape:'html':'UTF-8'}">
								<i class="icon-download"></i>
								{l s="Download"} ({Tools::formatBytes($attachment.file_size, 2)})
							</a>
							<hr>
						</div>
					{if $smarty.foreach.attachements.iteration %3 == 0 || $smarty.foreach.attachements.last}</div>{/if}
				{/foreach}
			</section>
			<!--end Download -->
			{/if}
			{if isset($product) && $product->customizable}
			<!--Customization -->
			<section class="page-product-box">
				<h3 class="page-product-heading">{l s='Product customization'}</h3>
				<!-- Customizable products -->
				<form method="post" action="{$customizationFormTarget}" enctype="multipart/form-data" id="customizationForm" class="clearfix">
					<p class="infoCustomizable">
						{l s='After saving your customized product, remember to add it to your cart.'}
						{if $product->uploadable_files}
						<br />
						{l s='Allowed file formats are: GIF, JPG, PNG'}{/if}
					</p>
					{if $product->uploadable_files|intval}
						<div class="customizableProductsFile">
							<h5 class="product-heading-h5">{l s='Pictures'}</h5>
							<ul id="uploadable_files" class="clearfix">
								{counter start=0 assign='customizationField'}
								{foreach from=$customizationFields item='field' name='customizationFields'}
									{if $field.type == 0}
										<li class="customizationUploadLine{if $field.required} required{/if}">{assign var='key' value='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}
											{if isset($pictures.$key)}
												<div class="customizationUploadBrowse">
													<img src="{$pic_dir}{$pictures.$key}_small" alt="" />
														<a href="{$link->getProductDeletePictureLink($product, $field.id_customization_field)|escape:'html':'UTF-8'}" title="{l s='Delete'}" >
															<img src="{$img_dir}icon/delete.gif" alt="{l s='Delete'}" class="customization_delete_icon" width="11" height="13" />
														</a>
												</div>
											{/if}
											<div class="customizationUploadBrowse form-group">
												<label class="customizationUploadBrowseDescription">
													{if !empty($field.name)}
														{$field.name}
													{else}
														{l s='Please select an image file from your computer'}
													{/if}
													{if $field.required}<sup>*</sup>{/if}
												</label>
												<input type="file" name="file{$field.id_customization_field}" id="img{$customizationField}" class="form-control customization_block_input {if isset($pictures.$key)}filled{/if}" />
											</div>
										</li>
										{counter}
									{/if}
								{/foreach}
							</ul>
						</div>
					{/if}
					{if $product->text_fields|intval}
						<div class="customizableProductsText">
							<h5 class="product-heading-h5">{l s='Text'}</h5>
							<ul id="text_fields">
							{counter start=0 assign='customizationField'}
							{foreach from=$customizationFields item='field' name='customizationFields'}
								{if $field.type == 1}
									<li class="customizationUploadLine{if $field.required} required{/if}">
										<label for ="textField{$customizationField}">
											{assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}
											{if !empty($field.name)}
												{$field.name}
											{/if}
											{if $field.required}<sup>*</sup>{/if}
										</label>
										<textarea name="textField{$field.id_customization_field}" class="form-control customization_block_input" id="textField{$customizationField}" rows="3" cols="20">{strip}
											{if isset($textFields.$key)}
												{$textFields.$key|stripslashes}
											{/if}
										{/strip}</textarea>
									</li>
									{counter}
								{/if}
							{/foreach}
							</ul>
						</div>
					{/if}
					<p id="customizedDatas">
						<input type="hidden" name="quantityBackup" id="quantityBackup" value="" />
						<input type="hidden" name="submitCustomizedDatas" value="1" />
						<button class="button btn btn-default button button-small" name="saveCustomization">
							<span>{l s='Save'}</span>
						</button>
						<span id="ajax-loader" class="unvisible">
							<img src="{$img_ps_dir}loader.gif" alt="loader" />
						</span>
					</p>
				</form>
				<p class="clear required"><sup>*</sup> {l s='required fields'}</p>	
			</section>
			<!--end Customization -->
			{/if}
		{/if}
		{if isset($packItems) && $packItems|@count > 0}
		<section id="blockpack">
			<h3 class="page-product-heading">{l s='Pack content'}</h3>
			{include file="$tpl_dir./product-list.tpl" products=$packItems}
		</section>
		{/if}

you have to remove this code. Instead of it use code that i pasted below:

        {* START OF EXTRA TABS BY MyPresta *}
        {* START OF EXTRA TABS BY MyPresta *}
        {* START OF EXTRA TABS BY MyPresta *}
        {* START OF EXTRA TABS BY MyPresta *}
        
        <div id="more_info_block" class="clear">
            <ul id="more_info_tabs" class="idTabs idTabsShort clearfix">
                {if $product->description}<li><a id="more_info_tab_more_info" href="#idTab1">{l s='More info'}</a></li>{/if}
                {if $features}<li><a id="more_info_tab_data_sheet" href="#idTab2">{l s='Data sheet'}</a></li>{/if}
                {if $attachments}<li><a id="more_info_tab_attachments" href="#idTab3">{l s='Download'}</a></li>{/if}
                {if isset($packItems) && $packItems|@count > 0}<li><a id="more_info_tab_pack" href="#blockpack">{l s='Pack Content'}</a></li>{/if}
                {if isset($accessories) AND $accessories}<li><a href="#idTabz4">{l s='Accessories'}</a></li>{/if}
                {if isset($product) && $product->customizable}<li><a href="#idTab15">{l s='Product customization'}</a></li>{/if}
                {$HOOK_PRODUCT_TAB}
            </ul>
            
            <div id="more_info_sheets" class="sheets align_justify">
                {if isset($product) && $product->description}
        			<!-- More info -->
        			<div id="idTab1" class="rte">
        				{$product->description}
        			</div>
        			<!--end  More info -->
	            {/if}
                
                
                {if isset($features) && $features}
        			<!-- Data sheet -->
        			<div id="idTab2" class="rte">
        				<table class="table-data-sheet">
        					{foreach from=$features item=feature}
        					<tr class="{cycle values="odd,even"}">
        						{if isset($feature.value)}
        						<td>{$feature.name|escape:'html':'UTF-8'}</td>
        						<td>{$feature.value|escape:'html':'UTF-8'}</td>
        						{/if}
        					</tr>
        					{/foreach}
        				</table>
        			</div>
        			<!--end Data sheet -->
                {/if}
                
                
			    {if isset($attachments) && $attachments}
        			<!--Download -->
        			<div id="idTab3" class="page-product-box">
        				{foreach from=$attachments item=attachment name=attachements}
        					{if $smarty.foreach.attachements.iteration %3 == 1}<div class="row">{/if}
        						<div class="col-lg-4">
        							<h4><a href="{$link->getPageLink('attachment', true, NULL, "id_attachment={$attachment.id_attachment}")|escape:'html':'UTF-8'}">{$attachment.name|escape:'html':'UTF-8'}</a></h4>
        							<p class="text-muted">{$attachment.description|escape:'html':'UTF-8'}</p>
        							<a class="btn btn-default btn-block" href="{$link->getPageLink('attachment', true, NULL, "id_attachment={$attachment.id_attachment}")|escape:'html':'UTF-8'}">
        								<i class="icon-download"></i>
        								{l s="Download"} ({Tools::formatBytes($attachment.file_size, 2)})
        							</a>
        							<hr />
        						</div>
        					{if $smarty.foreach.attachements.iteration %3 == 0 || $smarty.foreach.attachements.last}</div>{/if}
        				{/foreach}
        			</div>
        			<!--end Download -->
			    {/if}
                
                
                         {if isset($accessories) && $accessories}
                           <!--Accessories -->
                             <div id="idTabz4" class="page-product-box">
                               {include file="$tpl_dir./product-list.tpl" products=$accessories}
                             </div>
                           <!--end Accessories -->
                         {/if}
                
                
        		{if isset($packItems) && $packItems|@count > 0}
            		  <div id="blockpack">
            		    {include file="$tpl_dir./product-list.tpl" products=$packItems}
            		  </div>
        		{/if}
                
                
                {if isset($product) && $product->customizable}
        			<!--Customization -->
        			<div id="idTab15" class="page-product-box">
        				<!-- Customizable products -->
        				<form method="post" action="{$customizationFormTarget}" enctype="multipart/form-data" id="customizationForm" class="clearfix">
        					<p class="infoCustomizable">
        						{l s='After saving your customized product, remember to add it to your cart.'}
        						{if $product->uploadable_files}
        						<br />
        						{l s='Allowed file formats are: GIF, JPG, PNG'}{/if}
        					</p>
        					{if $product->uploadable_files|intval}
        						<div class="customizableProductsFile">
        							<h5 class="product-heading-h5">{l s='Pictures'}</h5>
        							<ul id="uploadable_files" class="clearfix">
        								{counter start=0 assign='customizationField'}
        								{foreach from=$customizationFields item='field' name='customizationFields'}
        									{if $field.type == 0}
        										<li class="customizationUploadLine{if $field.required} required{/if}">{assign var='key' value='pictures_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}
        											{if isset($pictures.$key)}
        												<div class="customizationUploadBrowse">
        													<img src="{$pic_dir}{$pictures.$key}_small" alt="" />
        														<a href="{$link->getProductDeletePictureLink($product, $field.id_customization_field)|escape:'html':'UTF-8'}" title="{l s='Delete'}" >
        															<img src="{$img_dir}icon/delete.gif" alt="{l s='Delete'}" class="customization_delete_icon" width="11" height="13" />
        														</a>
        												</div>
        											{/if}
        											<div class="customizationUploadBrowse form-group">
        												<label class="customizationUploadBrowseDescription">
        													{if !empty($field.name)}
        														{$field.name}
        													{else}
        														{l s='Please select an image file from your computer'}
        													{/if}
        													{if $field.required}<sup>*</sup>{/if}
        												</label>
        												<input type="file" name="file{$field.id_customization_field}" id="img{$customizationField}" class="form-control customization_block_input {if isset($pictures.$key)}filled{/if}" />
        											</div>
        										</li>
        										{counter}
        									{/if}
        								{/foreach}
        							</ul>
        						</div>
        					{/if}
        					{if $product->text_fields|intval}
        						<div class="customizableProductsText">
        							<h5 class="product-heading-h5">{l s='Text'}</h5>
        							<ul id="text_fields">
        							{counter start=0 assign='customizationField'}
        							{foreach from=$customizationFields item='field' name='customizationFields'}
        								{if $field.type == 1}
        									<li class="customizationUploadLine{if $field.required} required{/if}">
        										<label for ="textField{$customizationField}">
        											{assign var='key' value='textFields_'|cat:$product->id|cat:'_'|cat:$field.id_customization_field}
        											{if !empty($field.name)}
        												{$field.name}
        											{/if}
        											{if $field.required}<sup>*</sup>{/if}
        										</label>
        										<textarea name="textField{$field.id_customization_field}" class="form-control customization_block_input" id="textField{$customizationField}" rows="3" cols="20">{strip}
        											{if isset($textFields.$key)}
        												{$textFields.$key|stripslashes}
        											{/if}
        										{/strip}</textarea>
        									</li>
        									{counter}
        								{/if}
        							{/foreach}
        							</ul>
        						</div>
        					{/if}
        					<p id="customizedDatas">
        						<input type="hidden" name="quantityBackup" id="quantityBackup" value="" />
        						<input type="hidden" name="submitCustomizedDatas" value="1" />
        						<button class="button btn btn-default button button-small" name="saveCustomization">
        							<span>{l s='Save'}</span>
        						</button>
        						<span id="ajax-loader" class="unvisible">
        							<img src="{$img_ps_dir}loader.gif" alt="loader" />
        						</span>
        					</p>
        				</form>
        				<p class="clear required"><sup>*</sup> {l s='required fields'}</p>
        			</div>
        			<!--end Customization -->
			    {/if}
            
                <!-- extra tabs -->
                {$HOOK_PRODUCT_TAB_CONTENT}
                <!-- END extra tabs -->
            </div>
		   {if isset($HOOK_PRODUCT_FOOTER) && $HOOK_PRODUCT_FOOTER}{$HOOK_PRODUCT_FOOTER}{/if}
           
           {* END OF EXTRA TABS BY MyPresta *}
           {* END OF EXTRA TABS BY MyPresta *}
           {* END OF EXTRA TABS BY MyPresta *}
           {* END OF EXTRA TABS BY MyPresta *}

And that's all. Save changes and go to the next step related to css modifications.

 

CSS style modification

Go to theme directory and open /css/ sibdirectory. There is a global.css file. Open it, full path to file is: /themes/default-bootstrap/css/global.css. At the end of the code paste code:

.idTabs {
list-style-type:none;
margin-top:20px;
}
 
ul.idTabs li {
float:left;
margin-right:-1px;
}
 
.idTabs a {
color:#555454;
text-transform:uppercase;
font-family:"Open Sans",sans-serif;
font-weight:600;
font-size:18px;
line-height:60px;
position:relative;
border:1px solid #d6d4d4;
background:#fbfbfb;
margin:0 0 20px;
padding:14px 20px 17px;
}
 
#more_info_sheets .product_desc .block_description {
float:left;
margin-left:10px;
width:420px;
}
 
#more_info_sheets .product_desc .clear_product_desc {
clear:both;
height:0;
line-height:0;
}
 
.idTabs .selected,#header .sf-menu > li.sfHover > a,#header .sf-menu > li > a:hover,#header .sf-menu > li.sfHoverForce > a {
color:#fff;
background: #553D3D;
border-bottom-color: #000000;
text-decoration:none;
}

#more_info_sheets .rte {
    padding:10px!important;
}

#more_info_sheets .bx-wrapper {
  width:100%!important;
  max-width:none!important;
  display:block;
}

 

effect of modification:

Product Page tabs prestashop 1.6 real tabs

 

Remember that you can modify color of selected tab heading. It's easy, just change background param from #553D3D to any other color you want. You have to modify it  css code that you pasted to global.css file:

.idTabs .selected,#header .sf-menu > li.sfHover > a,#header .sf-menu > li > a:hover,#header .sf-menu > li.sfHoverForce > a {
color:#fff;
background: #553D3D;
border-bottom-color: #000000;
}

 

 

Compability with other modules

This modification change the way of how tabs appears in default template in ps 1.6. If you use some modules that add tabs to this section, you have to change the way of how tabs appears. It's easy. i will show you how to do it for default product comments module. Open file: /themes/default-bootstrap/modules/productcomments.tab.tpl - there is a code like:

<h3 id="#idTab5" class="idTabHrefShort page-product-heading">{l s='Reviews' mod='productcomments'}</h3> 

change it to:

<li><a href="#idTab5" class="idTabHrefShort page-product-heading">{l s='Reviews' mod='productcomments'}</a></li>

 

effect of module modification: reviews of product in tabbed view

product tabs prestashop

 

 

 

 

 

You can easily use the same way of modification for all other modules. After that you will have nice looking tabs with responsiveness in default-bootsrap template. My module to define extra tabs for product page supports this way of displaying  extra product tabs in prestashop 1.6

 

author milos myszczuk
Article by Milosz Myszczuk PrestaShop expert, official PrestaShop community moderator. PHP developer, specialist in relative and spatial databases management, GIS Analyst, CEO & founder of VEKIA interactive agency. Read more about VEKIA company
If you like my articles and want much more valuable tips, feel free to send me donation
1.4 version 1.4.11 1.6 404 addon admin advertise ahref ajax alpha animation api app application authentication back office backup badge banner basics block bootstrap button cache carrier cart catalog category certificate changelog chat class clear client clip cms code colors columns comments configuration contact container content controller cookie counter country coupon css csv currency customer dashboard database debug default delete delivery desktop developer device disable discount displayNav displayTop download dynamic editor effect empty encrypt engine error exchange exclude export facebook faceshop fade fancoupon fancybox fanpage fatal feature feed field file fix fixed font footer free friendly url front ftp full gallery generate gift global godaddy google google+ gray grid groupon header help hide highlight homefeatured homepage hook hosting hover howto htaccess html html5 ID image import include input instagram installation integration iPhone issue javascript jquery kgb knowhow languages law left likebox link list livingsocial loading log login logo loyality mail mailing maintenance manufacturer marketing marquee mcrypt menu meta mobile modification module movie moving multilanguage multiupload must have mysql news newsletter notification number open graph order override page password performance PHP phpmyadmin picture pinterest plugin popup post prestashop prestashop 1.0 prestashop 1.1 prestashop 1.2 prestashop 1.3 prestashop 1.4 prestashop 1.5 price rules problem product profile promotion proslider purifier quantity query quick tip random rates register reinsurance release reporting reset responsive restore results ribbon rich text right sales search security seo service shadow share shipping shop shopmania slider smarty social networks SQL SSL statistics stock store style subcategory superuser support switcher tab tablet tag tax template text theme tinyMCE tips and tricks tpl tracking translations tree trends trigger tumblr tutorial twitter update upgrade upload variables video visits voucher vulnerability web2print wide widget width window wishlist wysiwyg youtube zip zopim