<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NemoPS &#187; tabs</title>
	<atom:link href="http://nemops.com/tag/tabs/feed/" rel="self" type="application/rss+xml" />
	<link>http://nemops.com</link>
	<description>Prestashop Tutorials, Modules and More!</description>
	<lastBuildDate>Wed, 05 Dec 2018 13:25:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.35</generator>
	<item>
		<title>Product page tabs like 1.5 on Prestashop 1.6</title>
		<link>http://nemops.com/prestashop-1-6-product-page-tabs/</link>
		<comments>http://nemops.com/prestashop-1-6-product-page-tabs/#comments</comments>
		<pubDate>Wed, 15 Jul 2015 09:15:34 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Theming]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[product]]></category>
		<category><![CDATA[tabs]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2478</guid>
		<description><![CDATA[<p>Have you been missing the traditional product page tabs in the new Prestashop 1.6 Template? If so, see how to easily take them back. Let&#8217;s get some Prestashop 1.5 template code To start off, get some 1.5 template code and drop it into our 1.6. I chose 1.5.6.2 as it&#8217;s the latest 1.5 so far. [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-6-product-page-tabs/">Product page tabs like 1.5 on Prestashop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>Have you been missing the traditional product page tabs in the new Prestashop 1.6 Template? If so, see how to easily take them back.</p>
<p><span id="more-2478"></span></p>
<h2>Let&#8217;s get some Prestashop 1.5 template code</h2>
<p>To start off, get some 1.5 template code and drop it into our 1.6. I chose 1.5.6.2 as it&#8217;s the latest 1.5 so far. This is how it looks like, you can simply copy/paste it:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if (isset($product) &amp;&amp; $product-&gt;description) || (isset($features) &amp;&amp; $features) || (isset($accessories) &amp;&amp; $accessories) || (isset($HOOK_PRODUCT_TAB) &amp;&amp; $HOOK_PRODUCT_TAB) || (isset($attachments) &amp;&amp; $attachments) || isset($product) &amp;&amp; $product-&gt;customizable}
&lt;div id=&quot;more_info_block&quot; class=&quot;clear&quot;&gt;
	&lt;ul id=&quot;more_info_tabs&quot; class=&quot;idTabs idTabsShort clearfix&quot;&gt;
		{if $product-&gt;description}&lt;li&gt;&lt;a id=&quot;more_info_tab_more_info&quot; href=&quot;#idTab1&quot;&gt;{l s='More info'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if $features}&lt;li&gt;&lt;a id=&quot;more_info_tab_data_sheet&quot; href=&quot;#idTab2&quot;&gt;{l s='Data sheet'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if $attachments}&lt;li&gt;&lt;a id=&quot;more_info_tab_attachments&quot; href=&quot;#idTab9&quot;&gt;{l s='Download'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if isset($accessories) AND $accessories}&lt;li&gt;&lt;a href=&quot;#idTab4&quot;&gt;{l s='Accessories'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if isset($product) &amp;&amp; $product-&gt;customizable}&lt;li&gt;&lt;a href=&quot;#idTab10&quot;&gt;{l s='Product customization'}&lt;/a&gt;&lt;/li&gt;{/if}
		{$HOOK_PRODUCT_TAB}
	&lt;/ul&gt;
	&lt;div id=&quot;more_info_sheets&quot; class=&quot;sheets align_justify&quot;&gt;
	{if isset($product) &amp;&amp; $product-&gt;description}
		&lt;!-- full description --&gt;
		&lt;div id=&quot;idTab1&quot; class=&quot;rte&quot;&gt;{$product-&gt;description}&lt;/div&gt;
	{/if}
	{if isset($features) &amp;&amp; $features}
		&lt;!-- product's features --&gt;
		&lt;ul id=&quot;idTab2&quot; class=&quot;bullet&quot;&gt;
		{foreach from=$features item=feature}
            {if isset($feature.value)}
			    &lt;li&gt;&lt;span&gt;{$feature.name|escape:'htmlall':'UTF-8'}&lt;/span&gt; {$feature.value|escape:'htmlall':'UTF-8'}&lt;/li&gt;
            {/if}
		{/foreach}
		&lt;/ul&gt;
	{/if}
	{if isset($attachments) &amp;&amp; $attachments}
		&lt;ul id=&quot;idTab9&quot; class=&quot;bullet&quot;&gt;
		{foreach from=$attachments item=attachment}
			&lt;li&gt;&lt;a href=&quot;{$link-&gt;getPageLink('attachment', true, NULL, &quot;id_attachment={$attachment.id_attachment}&quot;)|escape:'html'}&quot;&gt;{$attachment.name|escape:'htmlall':'UTF-8'}&lt;/a&gt;&lt;br /&gt;{$attachment.description|escape:'htmlall':'UTF-8'}&lt;/li&gt;
		{/foreach}
		&lt;/ul&gt;
	{/if}
	{if isset($accessories) AND $accessories}
		&lt;!-- accessories --&gt;
		&lt;div id=&quot;idTab4&quot; class=&quot;bullet&quot;&gt;
			&lt;div class=&quot;block products_block accessories_block clearfix&quot;&gt;
				&lt;div class=&quot;block_content&quot;&gt;
					&lt;ul&gt;
					{foreach from=$accessories item=accessory name=accessories_list}
						{if ($accessory.allow_oosp || $accessory.quantity_all_versions &gt; 0 || $accessory.quantity &gt; 0) AND $accessory.available_for_order AND !isset($restricted_country_mode)}
							{assign var='accessoryLink' value=$link-&gt;getProductLink($accessory.id_product, $accessory.link_rewrite, $accessory.category)}
							&lt;li class=&quot;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&quot;&gt;
								&lt;p class=&quot;s_title_block&quot;&gt;
									&lt;a href=&quot;{$accessoryLink|escape:'htmlall':'UTF-8'}&quot;&gt;{$accessory.name|escape:'htmlall':'UTF-8'}&lt;/a&gt;
									{if $accessory.show_price AND !isset($restricted_country_mode) AND !$PS_CATALOG_MODE} - &lt;span class=&quot;price&quot;&gt;{if $priceDisplay != 1}{displayWtPrice p=$accessory.price}{else}{displayWtPrice p=$accessory.price_tax_exc}{/if}&lt;/span&gt;{/if}
								&lt;/p&gt;
								&lt;div class=&quot;product_desc&quot;&gt;
									&lt;a href=&quot;{$accessoryLink|escape:'htmlall':'UTF-8'}&quot; title=&quot;{$accessory.legend|escape:'htmlall':'UTF-8'}&quot; class=&quot;product_image&quot;&gt;&lt;img src=&quot;{$link-&gt;getImageLink($accessory.link_rewrite, $accessory.id_image, 'medium_default')|escape:'html'}&quot; alt=&quot;{$accessory.legend|escape:'htmlall':'UTF-8'}&quot; width=&quot;{$mediumSize.width}&quot; height=&quot;{$mediumSize.height}&quot; /&gt;&lt;/a&gt;
									&lt;div class=&quot;block_description&quot;&gt;
										&lt;a href=&quot;{$accessoryLink|escape:'htmlall':'UTF-8'}&quot; title=&quot;{l s='More'}&quot; class=&quot;product_description&quot;&gt;{$accessory.description_short|strip_tags|truncate:400:'...'}&lt;/a&gt;
									&lt;/div&gt;
									&lt;div class=&quot;clear_product_desc&quot;&gt;&amp;nbsp;&lt;/div&gt;
								&lt;/div&gt;
								
								&lt;p class=&quot;clearfix&quot; style=&quot;margin-top:5px&quot;&gt;
									&lt;a class=&quot;button&quot; href=&quot;{$accessoryLink|escape:'htmlall':'UTF-8'}&quot; title=&quot;{l s='View'}&quot;&gt;{l s='View'}&lt;/a&gt;
									{if !$PS_CATALOG_MODE &amp;&amp; ($accessory.allow_oosp || $accessory.quantity &gt; 0)}
									&lt;a class=&quot;exclusive button ajax_add_to_cart_button&quot; href=&quot;{$link-&gt;getPageLink('cart', true, NULL, &quot;qty=1&amp;amp;id_product={$accessory.id_product|intval}&amp;amp;token={$static_token}&amp;amp;add&quot;)|escape:'html'}&quot; rel=&quot;ajax_id_product_{$accessory.id_product|intval}&quot; title=&quot;{l s='Add to cart'}&quot;&gt;{l s='Add to cart'}&lt;/a&gt;
									{/if}
								&lt;/p&gt;
								
							&lt;/li&gt;
						{/if}
					{/foreach}
					&lt;/ul&gt;
				&lt;/div&gt;
			&lt;/div&gt;
		&lt;/div&gt;
	{/if}

	&lt;!-- Customizable products --&gt;
	{if isset($product) &amp;&amp; $product-&gt;customizable}
		&lt;div id=&quot;idTab10&quot; class=&quot;bullet customization_block&quot;&gt;
			&lt;form method=&quot;post&quot; action=&quot;{$customizationFormTarget}&quot; enctype=&quot;multipart/form-data&quot; id=&quot;customizationForm&quot; class=&quot;clearfix&quot;&gt;
				&lt;p class=&quot;infoCustomizable&quot;&gt;
					{l s='After saving your customized product, remember to add it to your cart.'}
					{if $product-&gt;uploadable_files}&lt;br /&gt;{l s='Allowed file formats are: GIF, JPG, PNG'}{/if}
				&lt;/p&gt;
				{if $product-&gt;uploadable_files|intval}
				&lt;div class=&quot;customizableProductsFile&quot;&gt;
					&lt;h3&gt;{l s='Pictures'}&lt;/h3&gt;
					&lt;ul id=&quot;uploadable_files&quot; class=&quot;clearfix&quot;&gt;
						{counter start=0 assign='customizationField'}
						{foreach from=$customizationFields item='field' name='customizationFields'}
							{if $field.type == 0}
								&lt;li class=&quot;customizationUploadLine{if $field.required} required{/if}&quot;&gt;{assign var='key' value='pictures_'|cat:$product-&gt;id|cat:'_'|cat:$field.id_customization_field}
									{if isset($pictures.$key)}
									&lt;div class=&quot;customizationUploadBrowse&quot;&gt;
										&lt;img src=&quot;{$pic_dir}{$pictures.$key}_small&quot; alt=&quot;&quot; /&gt;
										&lt;a href=&quot;{$link-&gt;getProductDeletePictureLink($product, $field.id_customization_field)|escape:'html'}&quot; title=&quot;{l s='Delete'}&quot; &gt;
											&lt;img src=&quot;{$img_dir}icon/delete.gif&quot; alt=&quot;{l s='Delete'}&quot; class=&quot;customization_delete_icon&quot; width=&quot;11&quot; height=&quot;13&quot; /&gt;
										&lt;/a&gt;
									&lt;/div&gt;
									{/if}
									&lt;div class=&quot;customizationUploadBrowse&quot;&gt;
										&lt;label class=&quot;customizationUploadBrowseDescription&quot;&gt;{if !empty($field.name)}{$field.name}{else}{l s='Please select an image file from your computer'}{/if}{if $field.required}&lt;sup&gt;*&lt;/sup&gt;{/if}&lt;/label&gt;
										&lt;input type=&quot;file&quot; name=&quot;file{$field.id_customization_field}&quot; id=&quot;img{$customizationField}&quot; class=&quot;customization_block_input {if isset($pictures.$key)}filled{/if}&quot; /&gt;
									&lt;/div&gt;
								&lt;/li&gt;
								{counter}
							{/if}
						{/foreach}
					&lt;/ul&gt;
				&lt;/div&gt;
				{/if}
				{if $product-&gt;text_fields|intval}
				&lt;div class=&quot;customizableProductsText&quot;&gt;
					&lt;h3&gt;{l s='Text'}&lt;/h3&gt;
					&lt;ul id=&quot;text_fields&quot;&gt;
					{counter start=0 assign='customizationField'}
					{foreach from=$customizationFields item='field' name='customizationFields'}
						{if $field.type == 1}
						&lt;li class=&quot;customizationUploadLine{if $field.required} required{/if}&quot;&gt;
							&lt;label for =&quot;textField{$customizationField}&quot;&gt;{assign var='key' value='textFields_'|cat:$product-&gt;id|cat:'_'|cat:$field.id_customization_field} {if !empty($field.name)}{$field.name}{/if}{if $field.required}&lt;sup&gt;*&lt;/sup&gt;{/if}&lt;/label&gt;
							&lt;textarea name=&quot;textField{$field.id_customization_field}&quot; id=&quot;textField{$customizationField}&quot; rows=&quot;1&quot; cols=&quot;40&quot; class=&quot;customization_block_input&quot;&gt;{if isset($textFields.$key)}{$textFields.$key|stripslashes}{/if}&lt;/textarea&gt;
						&lt;/li&gt;
						{counter}
						{/if}
					{/foreach}
					&lt;/ul&gt;
				&lt;/div&gt;
				{/if}
				&lt;p id=&quot;customizedDatas&quot;&gt;
					&lt;input type=&quot;hidden&quot; name=&quot;quantityBackup&quot; id=&quot;quantityBackup&quot; value=&quot;&quot; /&gt;
					&lt;input type=&quot;hidden&quot; name=&quot;submitCustomizedDatas&quot; value=&quot;1&quot; /&gt;
					&lt;input type=&quot;button&quot; class=&quot;button&quot; value=&quot;{l s='Save'}&quot; onclick=&quot;javascript:saveCustomization()&quot; /&gt;
					&lt;span id=&quot;ajax-loader&quot; style=&quot;display:none&quot;&gt;&lt;img src=&quot;{$img_ps_dir}loader.gif&quot; alt=&quot;loader&quot; /&gt;&lt;/span&gt;
				&lt;/p&gt;
			&lt;/form&gt;
			&lt;p class=&quot;clear required&quot;&gt;&lt;sup&gt;*&lt;/sup&gt; {l s='required fields'}&lt;/p&gt;
		&lt;/div&gt;
	{/if}

	{if isset($HOOK_PRODUCT_TAB_CONTENT) &amp;&amp; $HOOK_PRODUCT_TAB_CONTENT}{$HOOK_PRODUCT_TAB_CONTENT}{/if}
	&lt;/div&gt;
&lt;/div&gt;
{/if}

</pre>
<p>Copy the previous code. Then, open up <strong>product.tpl</strong>, which you can find in the theme&#8217;s folder, and locate this line:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if isset($features) &amp;&amp; $features}
			&lt;!-- Data sheet --&gt;
			&lt;section class=&quot;page-product-box&quot;&gt;
</pre>
<p>Right before that, paste in the 1.5 template code. We will need to make minor adjustments to it, but before diving deep into coding, let&#8217;s comment out the 1.6 code.<br />
Comment out everything from here:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if isset($features) &amp;&amp; $features}
</pre>
<p>To right <strong>before</strong></p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if isset($HOOK_PRODUCT_FOOTER) &amp;&amp; $HOOK_PRODUCT_FOOTER}{$HOOK_PRODUCT_FOOTER}{/if}
</pre>
<p>The result should be as follows:</p>
<pre class="brush: php; title: ; notranslate">
		{*if isset($features) &amp;&amp; $features}
			&lt;!-- Data sheet --&gt;
			&lt;section class=&quot;page-product-box&quot;&gt;
				&lt;h3 class=&quot;page-product-heading&quot;&gt;{l s='Data sheet'}&lt;/h3&gt;
				&lt;table class=&quot;table-data-sheet&quot;&gt;
					{foreach from=$features item=feature}
					&lt;tr class=&quot;{cycle values=&quot;odd,even&quot;}&quot;&gt;
						{if isset($feature.value)}
						&lt;td&gt;{$feature.name|escape:'html':'UTF-8'}&lt;/td&gt;
						&lt;td&gt;{$feature.value|escape:'html':'UTF-8'}&lt;/td&gt;
						{/if}
					&lt;/tr&gt;
					{/foreach}
				&lt;/table&gt;
			&lt;/section&gt;
			&lt;!--end Data sheet --&gt;


// WHOLE CODE BLOCK HERE...



					&lt;/div&gt;
				&lt;/div&gt;
			&lt;/section&gt;
			&lt;!--end Accessories --&gt;
		{/if*}
		{if isset($HOOK_PRODUCT_FOOTER) &amp;&amp; $HOOK_PRODUCT_FOOTER}{$HOOK_PRODUCT_FOOTER}{/if}
</pre>
<p>With the whole block commented out. Then, comment out what comes after the product footer hook as well</p>
<pre class="brush: php; title: ; notranslate">
&lt;!-- description &amp; features --&gt;
		{*if (isset($product) &amp;&amp; $product-&gt;description) || (isset($features) &amp;&amp; $features) || (isset($accessories) &amp;&amp; $accessories) || (isset($HOOK_PRODUCT_TAB) &amp;&amp; $HOOK_PRODUCT_TAB) || (isset($attachments) &amp;&amp; $attachments) || isset($product) &amp;&amp; $product-&gt;customizable}
			{if isset($attachments) &amp;&amp; $attachments}
	

		// WHOLE CODE BLOCK HERE...

				&lt;p class=&quot;clear required&quot;&gt;&lt;sup&gt;*&lt;/sup&gt; {l s='required fields'}&lt;/p&gt;
			&lt;/section&gt;
			&lt;!--end Customization --&gt;
			{/if}
		{/if*}
</pre>
<p>Pay extra attention to this step, there are a bunch of IF statements at the end of the block, which might cause a bad error if not commented out in the right place.</p>
<div class="separator"></div>
<h2>Adapting the code</h2>
<p>At this point, we need to adapt a couple of sections, to make sure they are compatible with 1.6. We will simply examine each section and replace the content with its newer counterpart when needed.</p>
<p>The first block is the product description, and there is really nothing to change here, as it&#8217;s the same across the two templates.</p>
<p><strong>Features</strong> (data sheet) is another one that can be left as it is.</p>
</p>
<p>THe following one would be attachments, looking like this in the 1.5 snippet:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{foreach from=$attachments item=attachment}
	&lt;li&gt;&lt;a href=&quot;{$link-&gt;getPageLink('attachment', true, NULL, &quot;id_attachment={$attachment.id_attachment}&quot;)|escape:'html'}&quot;&gt;{$attachment.name|escape:'htmlall':'UTF-8'}&lt;/a&gt;&lt;br /&gt;{$attachment.description|escape:'htmlall':'UTF-8'}&lt;/li&gt;
{/foreach}
</pre>
<p>Let&#8217;s compare it to the 1.6 version:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{foreach from=$attachments item=attachment name=attachements}
	{if $smarty.foreach.attachements.iteration %3 == 1}&lt;div class=&quot;row&quot;&gt;{/if}
		&lt;div class=&quot;col-lg-4&quot;&gt;
			&lt;h4&gt;&lt;a href=&quot;{$link-&gt;getPageLink('attachment', true, NULL, &quot;id_attachment={$attachment.id_attachment}&quot;)|escape:'html':'UTF-8'}&quot;&gt;{$attachment.name|escape:'html':'UTF-8'}&lt;/a&gt;&lt;/h4&gt;
			&lt;p class=&quot;text-muted&quot;&gt;{$attachment.description|escape:'html':'UTF-8'}&lt;/p&gt;
			&lt;a class=&quot;btn btn-default btn-block&quot; href=&quot;{$link-&gt;getPageLink('attachment', true, NULL, &quot;id_attachment={$attachment.id_attachment}&quot;)|escape:'html':'UTF-8'}&quot;&gt;
				&lt;i class=&quot;icon-download&quot;&gt;&lt;/i&gt;
				{l s=&quot;Download&quot;} ({Tools::formatBytes($attachment.file_size, 2)})
			&lt;/a&gt;
			&lt;hr /&gt;
		&lt;/div&gt;
	{if $smarty.foreach.attachements.iteration %3 == 0 || $smarty.foreach.attachements.last}&lt;/div&gt;{/if}
{/foreach}
</pre>
<p>Replacing it sounds like a good idea, so go ahead and do it. Simply paste over everything inside the foreach (<strong>make sure you also add the name=attachments part</strong>!).</p>
<p><strong>Accessories</strong> is another one we need to replace, so delete everything within the condition:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
	{if isset($accessories) AND $accessories}
		&lt;!-- accessories --&gt;
		&lt;div id=&quot;idTab4&quot; class=&quot;bullet&quot;&gt;

			// Delete everything inside
		&lt;/div&gt;
	{/if}

	&lt;!-- Customizable products --&gt;
</pre>
<p>Still making sure to retain the #idTab4 div</p>
<p>The last block of the 1.5 template concerns customizable data, and it&#8217;s better to replace the whole content here as well. Therefore, once more:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{if isset($product) &amp;&amp; $product-&gt;customizable}
	&lt;div id=&quot;idTab10&quot; class=&quot;bullet customization_block&quot;&gt;
		// Delete everything inside

	&lt;/div&gt;
{/if}

</pre>
<p>Remove everything inside that div with idTab10 as ID.</p>
<p>We should be done&#8230;almost! There is a leftover of the 1.6 section, <strong>Pack Items</strong>, which used to be elsewhere in 1.5. If you don&#8217;t want it to be part of tabbed data, you can simply uncomment the <strong>section</strong> as it is. Otherwise, read on.</p>
<div class="separator"></div>
<h2>Dealing with the Pack Items block</h2>
<p>We cannot simply copy and paste the pack items block, as that would result in a div having no parent link to call it among tabs. The first thing we therefore have to do is add a link pointing to it, in the tabs navigation bar:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
	&lt;ul id=&quot;more_info_tabs&quot; class=&quot;idTabs idTabsShort clearfix&quot;&gt;
		{if $product-&gt;description}&lt;li&gt;&lt;a id=&quot;more_info_tab_more_info&quot; href=&quot;#idTab1&quot;&gt;{l s='More info'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if $features}&lt;li&gt;&lt;a id=&quot;more_info_tab_data_sheet&quot; href=&quot;#idTab2&quot;&gt;{l s='Data sheet'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if $attachments}&lt;li&gt;&lt;a id=&quot;more_info_tab_attachments&quot; href=&quot;#idTab9&quot;&gt;{l s='Download'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if isset($accessories) AND $accessories}&lt;li&gt;&lt;a href=&quot;#idTab4&quot;&gt;{l s='Accessories'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if isset($product) &amp;&amp; $product-&gt;customizable}&lt;li&gt;&lt;a href=&quot;#idTab10&quot;&gt;{l s='Product customization'}&lt;/a&gt;&lt;/li&gt;{/if}
		{if isset($packItems) &amp;&amp; $packItems|@count &gt; 0}&lt;li&gt;&lt;a href=&quot;#blockpack&quot;&gt;{l s='Pack Items'}&lt;/a&gt;&lt;/li&gt;{/if}
		{$HOOK_PRODUCT_TAB}
	&lt;/ul&gt;
</pre>
<p>As you can see, I added a whole new line to handle the pack tab, which is referencing to a (still non existing) div with the id #blockpack. You can really choose any ID you want here, just making sure it matches in the following step.</p>
<p>Let&#8217;s not scroll back after the customization block:</p>
<pre class="brush: php; title: ; notranslate">
	{/if}

	{if isset($HOOK_PRODUCT_TAB_CONTENT) &amp;&amp; $HOOK_PRODUCT_TAB_CONTENT}{$HOOK_PRODUCT_TAB_CONTENT}{/if}
</pre>
<p><strong>Right before</strong> {if isset($HOOK_&#8230; } but <strong>after that closing {/if}</strong> (which was the customization condition), so in that only one empty line, add the following:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
	{if isset($packItems) &amp;&amp; $packItems|@count &gt; 0}
		&lt;div id=&quot;blockpack&quot;&gt;
			{include file=&quot;$tpl_dir./product-list.tpl&quot; products=$packItems}
		&lt;/div&gt;
	{/if}
</pre>
<p>Here is how it should look</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
{/if}
{if isset($packItems) &amp;&amp; $packItems|@count &gt; 0}
	&lt;div id=&quot;blockpack&quot;&gt;
		{include file=&quot;$tpl_dir./product-list.tpl&quot; products=$packItems}
	&lt;/div&gt;
{/if}
{if isset($HOOK_PRODUCT_TAB_CONTENT) &amp;&amp; $HOOK_PRODUCT_TAB_CONTENT}{$HOOK_PRODUCT_TAB_CONTENT}{/if}
</pre>
<p><a href="http://nemops.com/wp-content/uploads/2015/07/product_page_tabs_unstyled.png"><img src="http://nemops.com/wp-content/uploads/2015/07/product_page_tabs_unstyled.png" alt="Product Page tabs like 1.5 in Prestashop 1.6 - unstyled" width="658" height="630" class="aligncenter size-full wp-image-2479" /></a></p>
<p>You can now breathe. The worst part is done. Save and refresh, you should have a working tabs system, even if navigation links are stack one on top of the other. Let&#8217;s give it some style!</p>
<div class="separator"></div>
<h2>Styling Tabs in the Product page</h2>
<p>There is not much to do at this point. Open up <strong>product.css</strong>, located in the theme folder, css/, and paste in the following</p>
<pre class="brush: css; title: ; notranslate">

#more_info_tabs li {
  float:left;

}

#more_info_tabs li a {
  padding: 0 20px;
  color:white;
  line-height: 40px;
  height: 40px;
  display:block;
  background: #555;
}

#more_info_tabs li a:active {text-decoration:none;}
#more_info_tabs li a.selected {
  background:black;
  text-decoration:none;
}

</pre>
<p>I gave it some generic styling to have them look like tabs, so feel free to expand over the tutorial and make it prettier! We&#8217;re done!</p>
<p><a href="http://nemops.com/wp-content/uploads/2015/07/product_page_tabs_done.png"><img src="http://nemops.com/wp-content/uploads/2015/07/product_page_tabs_done-680x601.png" alt="Product Page tabs like 1.5 in Prestashop 1.6 - Final result" width="680" height="601" class="aligncenter size-large wp-image-2480" /></a></p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-1-6-product-page-tabs/">Product page tabs like 1.5 on Prestashop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-1-6-product-page-tabs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to create new homepage tabs in Prestashop 1.6</title>
		<link>http://nemops.com/prestashop-new-homepage-tabs/</link>
		<comments>http://nemops.com/prestashop-new-homepage-tabs/#comments</comments>
		<pubDate>Tue, 23 Sep 2014 12:32:51 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[homepage]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[tabs]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=2153</guid>
		<description><![CDATA[<p>In this quick tip we will see how easy it is to create new tabs for the homepage in Prestashop 1.6, by simply enabling two hooks in a module. The basics First, we need a skeleton. That is, a basic module to work with. You can choose an existing one, or follow along in creating [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-new-homepage-tabs/">How to create new homepage tabs in Prestashop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>In this quick tip we will see how easy it is to create new tabs for the homepage in Prestashop 1.6, by simply enabling two hooks in a module.</p>
<p><span id="more-2153"></span></p>
<h2>The basics</h2>
<p>First, we need a skeleton. That is, a basic module to work with. You can choose an existing one, or follow along in creating a simple new module for this sole purpose. In the first case, you can jump directly to the next section.</p>
<p>We will not extensively see how to create a Prestashop Module from scratch; therefore, if you need more information about the topic you can have a look at the official Prestashop documentation on <strong><a href="http://doc.prestashop.com/display/PS15/Creating+a+PrestaShop+module" title="creating a Prestashop Module">creating a Prestashop Module</a></strong>.</p>
<p>That said, let&#8217;s create the module&#8217;s folder. Inside <em>modules/</em>, create one named <strong>pshometabs</strong> (or whatever name you prefer, as long as you remind it later on). Then, inside it, create a file named <strong>phometabs.php</strong>. We will not add any icon to the module, as it&#8217;s only meant to demonstrate the procedure. Open up the file and paste the following after an opening php tag:</p>
<pre class="brush: php; title: ; notranslate">


if (!defined('_PS_VERSION_'))
	exit;

class psHomeTabs extends Module
{
	
	public function __construct()
	{
		$this-&gt;name = 'pshometabs';
		$this-&gt;tab = 'front_office_features';
		$this-&gt;version = '1.0';
		$this-&gt;author = 'Nemo';
		$this-&gt;need_instance = 0;

	 	parent::__construct();

		$this-&gt;displayName = $this-&gt;l('PS new homepage tabs');
		$this-&gt;description = $this-&gt;l('Adds a new block to the homepage tabs.');
		$this-&gt;confirmUninstall = $this-&gt;l('Are you sure you want to delete this module?');
	}
	
	public function install()
	{
		if (!parent::install())
			return false;
		return true;
	}
	
}

</pre>
<p>And these are only the barebones of a Prestashop Module. It&#8217;s not doing anything of course, so let&#8217;s register some hooks for the home tabs.</p>
<div class="separator"></div>
<h2>Registering hooks for the home tabs</h2>
<p>First off, we need to support both of the hooks needed for home tabs. They are two, because one displays the label (e.g. Top sellers) and the other the content. Therefore, add the following content to the module&#8217;s class:</p>
<pre class="brush: php; title: ; notranslate">
	public function hookDisplayHomeTab($params)
	{
		return $this-&gt;display(__FILE__, 'tab.tpl');
	}

	public function hookDisplayHomeTabContent($params)
	{
		return $this-&gt;display(__FILE__, 'tab_content.tpl');
	}

</pre>
<p>We could as well be done with php and focus on templating now, but to make our life easier (instead of having to manually register hooks from Modules -> Positions in the back office), let&#8217;s do it in the install() method:</p>
<pre class="brush: php; title: ; notranslate">
	public function install()
	{
		if (!parent::install() OR
			!$this-&gt;registerHook('displayHomeTab') OR
			!$this-&gt;registerHook('displayHomeTabContent'))
			return false;
		return true;
	}
</pre>
<p>Save, login to the back office and test if the module is correctly installing. If it is, move on to creating template files.</p>
<div class="separator"></div>
<h2>Creating the hooks template files</h2>
<p>At this point, we need to display something. But what? Indeed, we need to know what displays where, and if you didn&#8217;t guess it already by the name, <strong>hookDisplayHomeTab</strong> is for the label, while <strong>hookDisplayHomeTabContent</strong> is, needless to say, for the content. Therefore, we need to write the proper label code within the tab.tpl file, and content inside tab_content.tpl. Of course, these files can have other names as well, as long as everything is consistent.</p>
<p>Create the following folder structure inside the module&#8217;s folder: <em>views/templates/hook/</em>. Inside this last one, start by adding the file named <strong>tab.tpl</strong>, and open it, pasting the following inside</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;li&gt;&lt;a data-toggle=&quot;tab&quot; href=&quot;#pshometabs&quot; class=&quot;pshometabs&quot;&gt;{l s='New Tab' mod='pshometabs'}&lt;/a&gt;&lt;/li&gt;
</pre>
<p>Please notice the content <strong>needs</strong> to have this exact structure if you use the default Prestashop 1.6 template. So you need it to contain a list item, and an anchor tag with the data-toggle attribute, as well as href pointing to the id of the content (which we don&#8217;t have yet). Again, names are extremely important at this stage, make sure there are no duplicates or things won&#8217;t work properly.</p>
<p>Lastly, create <strong>tab_content</strong> and paste the following:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">
&lt;ul id=&quot;pshometabs&quot; class=&quot;pshometabs tab-pane&quot;&gt;
	&lt;li&gt;
		{l s='This is a test message.' mod='pshometabs'}
	&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>Once more, to be consistent with the default theme, use an ul element with the related id used in the tab part. Make sure it has tab-pane as class, at least. And of course, an li as child, which can contain virtually anything you want.</p>
<p>Save and refresh, if you did everything correctly, after installing it the new tab will appear in the homepage:</p>
<p><a href="http://nemops.com/wp-content/uploads/2014/09/new_home_tabs.png"><img src="http://nemops.com/wp-content/uploads/2014/09/new_home_tabs-680x262.png" alt="How to create new homepage tabs in Prestashop 1.6 - Final Result" width="680" height="262" class="aligncenter size-large wp-image-2155" /></a></p>
<div class="separator"></div>
<h2>Side notes on the template files</h2>
<p>The previous code is meant to work with the default Prestashop 1.6 template. If you use a custom one, I strongly advise you to check how modules hooked to the homepage tabs are buil in the theme folder, modules (e.g. homefeatured). Then, mimic the same structure for the tab and tab content templates.</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-new-homepage-tabs/">How to create new homepage tabs in Prestashop 1.6</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-new-homepage-tabs/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Adding new tabs and fields to Prestashop products&#8217; back office</title>
		<link>http://nemops.com/prestashop-products-new-tabs-fields/</link>
		<comments>http://nemops.com/prestashop-products-new-tabs-fields/#comments</comments>
		<pubDate>Wed, 11 Sep 2013 14:02:38 +0000</pubDate>
		<dc:creator><![CDATA[Nemo]]></dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[back office]]></category>
		<category><![CDATA[prestashop]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[tabs]]></category>

		<guid isPermaLink="false">http://nemops.com/?p=1537</guid>
		<description><![CDATA[<p>It is easy enough to modify Prestashop’s products&#8217; back office and add new fields by editing the AdminProductsController. However, by using a module and a new tab, it becomes much more maintainable! Prestashop back office hooks Although we will go through the basics of setting up a module, this tutorial assumes you already know how [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-products-new-tabs-fields/">Adding new tabs and fields to Prestashop products&#8217; back office</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>It is easy enough to modify Prestashop’s products&#8217; back office and add new fields by editing the AdminProductsController. However, by using a module and a new tab, it becomes much more maintainable!</p>
<p><span id="more-1537"></span></p>
<a class="download-files button style1" href="http://nemops.com/wp-content/uploads/2013/09/Adding_new_fields_nemops.zip" title="Download Project Files">Download Project Files</a>
<h2>Prestashop back office hooks</h2>
<p>Although we will go through the basics of setting up a module, this tutorial assumes you already know how to create one from scratch. If you are totally new to Prestashop, I strongly recommend that you read the <a href="http://doc.prestashop.com/display/PS15/Creating+a+PrestaShop+module" title="How to create a Prestashop Module" target="_blank">Official documentation on how to create a Prestashop Module</a> before approaching this tutorial.</p>
<p>Now, in order to add new fields to Prestashop&#8217;s products&#8217; back office, it is essential to be aware of the hooks that can be used to perform various operations in the admin panel. Specifically, we will be using the following ones:</p>
<p><strong>DisplayAdminProductsExtra</strong>: this hook adds new tabs to the product&#8217;s back office interface, thus, we will use this hook to plug in our new content&#8217;s input field with translations</p>
<p><strong>ActionAdminControllerSetMedia</strong>: if we ever need to style our new tab, or add custom javascript functions, this is the ideal hook to use to plug css and js files. This is called for every Prestashop Admin page, thus we will need to prevent it from running in pages that are not the product&#8217;s configuration.</p>
<p><strong>ActionProductUpdate</strong>: the new field needs to be saved in the database. Specifically, we will add a new column (custom_field) to the product_lang table and add a new translatable field, without using overrides at all. By plugging code snippets into this hook, we can easily update the column when the product itself is updated.</p>
<p>At this point, we can line out our plan of action: after giving the module a basic setup, we will first create the template file that will display the new field&#8217;s input box on its own table. Then, we will see how to overcome a little issue with translatable fields, using the <strong>ActionAdminControllerSetMedia</strong> hook, and lastly, on data submission, we will update the new custom field once the product is updated. We will create a new field for demonstrational purposes only, but feel free to dare beyond the limits of this tutorial if you want!</p>
<div class="separator"></div>
<h2>Setting up the module</h2>
<p>First of all, let&#8217;s start with a simple module template. You can download the blank module folder from the link at the beginning of the article. Drop the newfieldstut folder (the one from the &#8220;Start here&#8221; archive!) in the <em>modules/</em> folder of your Prestashop Root. Then open up <strong>newfieldstut.php</strong> and start by adding some regular module&#8217;s code.</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

if (!defined('_PS_VERSION_'))
	exit;

class newFieldsTut extends Module
{
	/* @var boolean error */
	protected $_errors = false;
	
	public function __construct()
	{
		$this-&gt;name = 'newfieldstut';
		$this-&gt;tab = 'front_office_features';
		$this-&gt;version = '1.0';
		$this-&gt;author = 'Nemo';
		$this-&gt;need_instance = 0;

	 	parent::__construct();

		$this-&gt;displayName = $this-&gt;l('New Fields Tutorial');
		$this-&gt;description = $this-&gt;l('Test module from Nemo\'s Post Scriptum Tutorial (nemops.com).');
	}
		
}
?&gt;
</pre>
<p>Now that the basic structure is laid out, we want to specify the install and uninstall functions. Let&#8217;s add a new column to product_lang with an ALTER TABLE, and provide a way to remove it if this module is uninstalled:</p>
<pre class="brush: php; title: ; notranslate">

	public function install()
	{
		if (!parent::install() OR
			!$this-&gt;alterTable('add') OR			
			!$this-&gt;registerHook('actionAdminControllerSetMedia') OR
			!$this-&gt;registerHook('actionProductUpdate') OR
			!$this-&gt;registerHook('displayAdminProductsExtra'))
			return false;
		return true;
	}
	
	public function uninstall()
	{
		if (!parent::uninstall() OR !$this-&gt;alterTable('remove'))
			return false;
		return true;
	}


	public function alterTable($method)
	{
		switch ($method) {
			case 'add':
				$sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'product_lang ADD `custom_field` TEXT NOT NULL';
				break;
			
			case 'remove':
				$sql = 'ALTER TABLE ' . _DB_PREFIX_ . 'product_lang DROP COLUMN `custom_field`';
				break;
		}
		
		if(!Db::getInstance()-&gt;Execute($sql))
			return false;
		return true;
	}
</pre>
<p><strong>Explanation:</strong> A couple of things here! First, in the <strong>install</strong> method, we</p>
<ul>
<li>1- As with every module, call the parent&#8217;s install method</li>
<li>2- Alter the product_lang table, to add the new field</li>
<li>3- Register all the hooks we will use</li>
</ul>
<p>Notice how I decided to structure the <strong>alterTable</strong> method. To avoid creating two functions, I stacked together the drop and add statements, passing a <strong>$method</strong> variable to determine what the function should do. Therefore, we call alterTable with &#8216;add&#8217; when installing, and &#8216;remove&#8217; when uninstalling.</p>
<p>Now, just to be sure we did everything correctly without errors, let&#8217;s try installing the module! Reach the <strong>Modules</strong> page in the back office and look for <strong>New Fields Tutorial</strong> in the modules list, as shown below.</p>
<p><img src="http://nemops.com/wp-content/uploads/2013/09/new_fields_module-680x254.png" alt="Our module in the Prestashop modules list" width="680" height="254" class="alignnone size-large wp-image-1552" /></p>
<p>Click install, and see if it works. If it does, move on to the next step!</p>
<div class="separator"></div>
<h2>Creating a new tab in the Product Back Office (DisplayAdminProductsExtra)</h2>
<p>Okay, our module is installed, and the hooks have been registered as well. Time to test it out! Add the following function to your module:</p>
<pre class="brush: php; title: ; notranslate">
	public function hookDisplayAdminProductsExtra($params)
	{
		if (Validate::isLoadedObject($product = new Product((int)Tools::getValue('id_product'))))
		{

			return $this-&gt;display(__FILE__, 'newfieldstut.tpl');
		}
	}	
</pre>
<p><strong>Explanation:</strong> first, we make sure the current product object is correctly loaded; if so we display the content of the module&#8217;s tpl file. Reach a product&#8217;s back office page; you should see something like this, by clicking on the new tab:</p>
<p><img src="http://nemops.com/wp-content/uploads/2013/09/productbo_start.png" alt="New tab to Prestashop Products&#039; back office" width="593" height="600" class="alignnone size-full wp-image-1553" /></p>
<p>At this point, we can start filling in the tpl file. Open up <strong>newfieldstut.tpl</strong>, get rid of the placeholder text and add the following instead:</p>
<pre class="brush: php; html-script: true; title: ; notranslate">

&lt;h4&gt;{l s='New Fields Tutorial' mod='newfieldstut'}&lt;/h4&gt;
&lt;div class=&quot;separation&quot;&gt;&lt;/div&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;td class=&quot;col-left&quot;&gt;
			&lt;label&gt;{l s='Our New Field:'}&lt;/label&gt;
		&lt;/td&gt;
		&lt;td&gt;
			{include file=&quot;controllers/products/input_text_lang.tpl&quot;
				languages=$languages
				input_name='custom_field'
				input_value=$custom_field}
			&lt;p class=&quot;preference_description&quot;&gt;{l s='Simply a new custom field'}. &lt;strong&gt;{l s='ie: something here as a hint'}&lt;/strong&gt;&lt;/p&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
</pre>
<p>Do not test this out yet! It will not work. Why? Let&#8217;s have a look at what we just did: first, we setup a simple table structure imitating the one Prestashop uses by default in the Product configuration page. Then, inside the rightmost table cell (td), we include a template file Prestashop kindly provides. This file is <strong>input_text_lang.tpl</strong>, and it is located in the admin theme folder, inside the controller section for products. What it does, is it provides a standardized way to add new translatable fields without having to mess with foreach loops in our own code. We can assign the currently available languages, name of the new input field and its value.</p>
<p>However, if we were to refresh the page now, and turn on error reporting, this is what we would see:</p>
<p><img src="http://nemops.com/wp-content/uploads/2013/09/product_bo_error-680x667.png" alt="Error before adding variables to the hook" width="680" height="667" class="alignnone size-large wp-image-1554" /></p>
<p>This happens because we have not assigned any of those 2 variables we mention in the code: <strong>$languages</strong> and <strong>$custom_field</strong>. Let&#8217;s take care of this.</p>
<p>Back to <strong>newfieldstut.php</strong>, create a new method as follows:</p>
<pre class="brush: php; title: ; notranslate">

	public function prepareNewTab()
	{

		$this-&gt;context-&gt;smarty-&gt;assign(array(
			'custom_field' =&gt; '',
			'languages' =&gt; $this-&gt;context-&gt;controller-&gt;_languages,
			'default_language' =&gt; (int)Configuration::get('PS_LANG_DEFAULT')
		));

	}

</pre>
<p>For the time being, we will not bother adding a real value to the new field. As for the other 2 variables, we get the currently available languages by the controller itself, and the default language for our store.</p>
<p>At this point, amend <strong>hookDisplayAdminProductsExtra</strong> as follows:</p>
<pre class="brush: php; title: ; notranslate">
	public function hookDisplayAdminProductsExtra($params)
	{
		if (Validate::isLoadedObject($product = new Product((int)Tools::getValue('id_product'))))
		{
			$this-&gt;prepareNewTab();
			return $this-&gt;display(__FILE__, 'newfieldstut.tpl');
		}
	}	
</pre>
<p>The new tab is ready! &#8230;.BUT! Hey, watch closely at what happens if you wait a couple of seconds before accessing it, or click its label right after the page reloads!</p>
<p>The language flags pops out after a while, or <strong>does not appear at all!</strong></p>
<p>This is (I believe) yet another Prestashop bug. If we want our new translatable field to work correctly every time, we absolutely need to take this bug off. How to?</p>
<div class="separator"></div>
<h2>Properly enabling multilanguage fields in the product Back Office</h2>
<p>What on earth is going on here? Basically, Prestashop loads the language translations flags using javascript. Not only this, but it also loads each tab asynchronously with Ajax, and &#8216;forgets&#8217; to call the function which assigns those flags for custom tabs. This is where the <strong>ActionAdminControllerSetMedia</strong> hook becomes useful! We will plug in a new javascript file to take it into account, so that flags are assigned to our new tab as well.</p>
<p>First off, open up <strong>newfieldstut.js</strong>, which you can find in the project&#8217;s module folder you already know. Here is how it will look:</p>
<pre class="brush: jscript; title: ; notranslate">
$(document).ready(function() {

});
</pre>
<p>Nothing but a simple jQuery ready statement. Inside, add the following</p>
<pre class="brush: jscript; title: ; notranslate">

	$(&quot;#product-tab-content-ModuleNewfieldstut&quot;).on('loaded', function(){
			displayFlags(languages, id_language, allowEmployeeFormLang);
	})

</pre>
<p>And that&#8217;s it, really. A few notes though: Notice the ID we are checking the <strong>load</strong> status for. This will vary depending on the name you give your module, and you can check it by inspecting the tab element with the browser&#8217;s developer tools:</p>
<p><img src="http://nemops.com/wp-content/uploads/2013/09/inpect_element-680x269.jpg" alt="Inspecting the Product tab id in the back office" width="680" height="269" class="alignnone size-large wp-image-1555" /></p>
<p>Just bear in mind you have to point the right ID, nothing else.</p>
<p>Now, back to <strong>newfieldstut.php</strong> once more. Add the following method:</p>
<pre class="brush: php; title: ; notranslate">
	public function hookActionAdminControllerSetMedia($params)
	{

		// add necessary javascript to products back office
		if($this-&gt;context-&gt;controller-&gt;controller_name == 'AdminProducts' &amp;&amp; Tools::getValue('id_product'))
		{
			$this-&gt;context-&gt;controller-&gt;addJS($this-&gt;_path.'/js/newfieldstut.js');
		}

	}
</pre>
<p><strong>Explanation:</strong> As we saw at the beginning of the article, this hook runs for every page of the back office. Thus, we need to be sure we are embedding our javascript for the single product configuration page only. Therefore, we first check the the current controller is <strong>AdminProducts</strong>, then, to be sure we are not viewing the products list, we also make sure a product id is set in the current url. After performing these checks, we simply use a regular addJS to embed the code.</p>
<p>Save &#038; refresh, at this point the language flags are always added to the new tab!</p>
<div class="separator"></div>
<h2>Saving and retrieving the new value</h2>
<p>Everything is in place, but we are not doing anything now. We are not displaying the new field value, nor are we able to save its content!</p>
<p>First off, let&#8217;s save the value for each language inside the database. Append the following method to our beloved <strong>newfieldstut.php</strong>:</p>
<pre class="brush: php; title: ; notranslate">

	public function hookActionProductUpdate($params)
	{
		// get all languages
		// for each of them, store the new field

		$id_product = (int)Tools::getValue('id_product');

		$languages = Language::getLanguages(true);
		foreach ($languages as $lang) {
			if(!Db::getInstance()-&gt;update('product_lang', array('custom_field'=&gt; pSQL(Tools::getValue('custom_field_'.$lang['id_lang']))) ,'id_lang = ' . $lang['id_lang'] .' AND id_product = ' .$id_product ))
				$this-&gt;context-&gt;controller-&gt;_errors[] = Tools::displayError('Error: ').mysql_error();
		}

	}

</pre>
<p><strong>Explanation:</strong> the hook we are targeting here(<strong>ActionProductUpdate</strong>) runs at the very same time a product&#8217;s data is stored inside the database. The perfect time to add our new content! First, we retrieve the current product ID, and then get all the currently active languages. For each of the languages, we update the database field for the matching language and product id. If the update operation cannot be completed, we spawn an error using the default Prestashop error handler for Admin tabs.</p>
<p>A small note on <strong>Tools::getValue(&#8216;custom_field_&#8217;.$lang[&#8216;id_lang&#8217;])</strong>: if you remember, we called our new field &#8216;custom_field&#8217; when embedding the translatable input box. This means Prestashop generates one field, appending each language id, for each language. Thus, we end up having custom_field_1, custom_field_2 etc&#8230; Where the number after the second underscore represents the language ID. That&#8217;s why we are targeting it like this &#8216;custom_field_&#8217;.$lang[&#8216;id_lang&#8217;], to be sure each language is correctly added.</p>
<p>Now, let&#8217;s try inputting different values for each languages, and hit &#8216;Save and stay&#8217;. Then, since we are not yet retrieving the field, let&#8217;s check it out in the database.</p>
<p><img src="http://nemops.com/wp-content/uploads/2013/09/database_entries.jpg" alt="Our custom fields in the Prestashop Database" width="501" height="341" class="alignnone size-full wp-image-1556" /></p>
<p>Okay, it&#8217;s done! At this point, we only need to retrieve those values! Let&#8217;s add a new method to our friend <strong>newfieldstut.php</strong>:</p>
<pre class="brush: php; title: ; notranslate">

	public function getCustomField($id_product)
	{
		$result = Db::getInstance()-&gt;ExecuteS('SELECT custom_field, id_lang FROM '._DB_PREFIX_.'product_lang WHERE id_product = ' . (int)$id_product);
		if(!$result)
			return array();

		foreach ($result as $field) {
			$fields[$field['id_lang']] = $field['custom_field'];
		}

		return $fields;
	}

</pre>
<p><strong>Explanation:</strong> Quite simply, using the product id as source data, we retrieve all entries for the <strong>custom_field</strong> column. Then, we format it for an array whose keys are language ids, and values the custom field value for that specific language. This is how Prestashop will be able to use them in the template: array(&#8216;5&#8242; => &#8216;value for id_lang 5), &#8230;&#8217;).</p>
<p>Of course, as a last step we call this function when assigning variables in <strong>prepareNewTab</strong>:</p>
<pre class="brush: php; title: ; notranslate">

	public function prepareNewTab()
	{

		$this-&gt;context-&gt;smarty-&gt;assign(array(
			'custom_field' =&gt; $this-&gt;getCustomField((int)Tools::getValue('id_product')),
			'languages' =&gt; $this-&gt;context-&gt;controller-&gt;_languages,
			'default_language' =&gt; (int)Configuration::get('PS_LANG_DEFAULT')
		));

	}

</pre>
<p>And we are finished!</p>
<p><img src="http://nemops.com/wp-content/uploads/2013/09/completed-680x488.png" alt="The new custom field added to Prestashop Products&#039; back office" width="680" height="488" class="alignnone size-large wp-image-1558" /></p>
<div class="separator"></div>
<h2>Conclusion</h2>
<p>As you could see, adding new fields to products using modules, without any remote sign of overrides, is not as complex as it might seem. Moreover, it&#8217;s a much more maintainable practice than messing with the original back office templates and controllers! Of course, at this point, you can take this tutorial further and add front office hooks to display your new, translatable field!</p>
<div class="separator">&nbsp;</div>
<h3>Additional Resources</h3>
<ul>
<li><a target="_blank" href="http://doc.prestashop.com/display/PS15/Creating+a+PrestaShop+module" title="How to create a Prestashop Module">Official documentation on how to create a Prestashop Module</a></li>
</ul>
<p>The post <a rel="nofollow" href="http://nemops.com/prestashop-products-new-tabs-fields/">Adding new tabs and fields to Prestashop products&#8217; back office</a> appeared first on <a rel="nofollow" href="http://nemops.com">NemoPS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemops.com/prestashop-products-new-tabs-fields/feed/</wfw:commentRss>
		<slash:comments>77</slash:comments>
		</item>
	</channel>
</rss>
