group rows by first character in foreach - php

I have foreach loop
{foreach from=$rootCategories item=category}
<li id="parentCategory" data-category="{$category.id_category}">
<span>
<img alt="{$category.name}" src="{$base_dir}img/c/{$category.id_category}.jpg" width='46' height='26'>
<h1>{$category.name}</h1>
</span>
</li>
{/foreach}
Current output is:
Ajp Alter beta black cpanle cupa
I want it to be
A Ajp Alter
B beta black
C cpanle cupa
I have used that code in foreach
$lastFoundLetter = '';
$firstLetter = {$category.name|substr:0:1}
{if {$firstLetter} != {$lastFoundLetter}} //you've started a new letter category
{if {$lastFoundLetter} != ''} //if there's a real value in $lastFoundLetter, we need to close the previous div </div>
{/if }
<div id="{$firstLetter}"> {$firstLetter} "<br/>"
{ $lastFoundLetter} = {$firstLetter}; </div>
{/if}
but its not working i think i have used wrong code.Guys plz help me

Code for changed question :
{assign var = 'lastFoundLetter' value= ''}
{foreach from=$rootCategories item=category}
{assign var = 'curFirstLetter' value= {$category.name|substr:0:1|upper}}
{if $curFirstLetter neq $lastFoundLetter}
{if $lastFoundLetter neq ''}<br />{/if}
{$curFirstLetter}
{assign var = 'lastFoundLetter' value=$curFirstLetter}
{/if}
{$category.name}
{/foreach}

That code will do what you want:
{assign var = 'lastFoundLetter' value= ''}
{foreach from=$rootCategories item=category}
{assign var = 'curFirstLetter' value= {$category.name|substr:0:1|upper}}
{if $curFirstLetter neq $lastFoundLetter}
{$curFirstLetter}
{assign var = 'lastFoundLetter' value=$curFirstLetter}
{$category.name}
{else}
{$category.name}
{/if}
<br />
{/foreach}
It was tested in newest Smarty 3.1.18
Result for this code is:
A Ajp
Alter
B beta
black
C cpanle
cupa
so the same you expected

Related

Assign var only if every product in cart is part of the same category

I'm trying to assign a var to be used in an if statement it looks like this:
{assign var="worldwide" value=false}
{assign var="idCategory" value=15}
{foreach from=$cart.products item=product}
{if $product.id_category_default == $idCategory}
{assign var="worldwide" value=true}
{/if}
{/foreach}
{if $worldwide == true}
{/if}
In its current state it however is true if just one product of category value 15 is in cart. I want it so that it is only true if all products in cart are part of same category. I'm using Prestashop 1.7
Use the cycle in reverse and abort when one of the elements is not what you want, like this:
{assign var="worldwide" value=true}
{assign var="idCategory" value=15}
{foreach from=$cart.products item=product}
{if $product.id_category_default != $idCategory}
{assign var="worldwide" value=false}
{break}
{/if}
{/foreach}
{if $worldwide == true}
{/if}

Smarty {capture} returns empty

I'm attempting to create a navigation while using smarty for the first time. I want to display all categories except one which I want to capture and use later on.
I got it to work and get the categories and put them in list. However that one category which is being captured, does not display where I want it to display.
my categories
Soccer //
subCat1 // those categories should be captured
subCat2 //
subCat3 //
Rugby
subCat1
subCat2
subCat3
Netball
subCat1
subCat2
subCat3
etc...
so my code goes like this:
<div>
<!-- deal with category levels -->
{if empty($category_level)}
{assign var="category_level" value=1}
{else}
{math equation="x + 1" x=$category_level assign="category_level"}
{/if}
{assign var="captured" value="false"}
{foreach from=$categories item="category"}
{if (strstr($category.name, 'Soccer') == true)}
{assign var="captured" value="y"}
{assign var="capItem" value="soccerCats"} <!-- used it to see whether the condition was met and this code has been run -- this has been assigned corerctly -->
{capture name="soccerCats" assign="soco"} <!-- start capturing if above condition was met -->
{/if}
{if $category.level == $category_level && $category.is_visible == "Yes"}
<ul>
<li class="{$category.name|htmlspecialchars}Cat">{$category.name|htmlspecialchars}<a class="mobileOnly"><i class="fa fa-angle-down fa-fw"></i></a>
{if !empty($category.children)}
<ul>
{assign var="categories" value=$category.children}
{if empty($category_level)}
{assign var="category_level" value=1}
{else}
{math equation="x + 1" x=$category_level assign="category_level"}
{/if}
{foreach from=$categories item="category"}
{if $category.level == $category_level && $category.is_visible == "Yes"}
<li>{$category.name|htmlspecialchars}</li>
{/if}
{/foreach}
{math equation="x - 1" x=$category_level assign="category_level"}
{assign var="category" value=0}
</ul>
{/if}
</li>
</ul>
{/if}
{if $captured == "y"}
{/capture} <!-- end the capture -->
{assign var="captured" value="n"}
{/if}
{/foreach}
{math equation="x - 1" x=$category_level assign="category_level"}
{assign var="category" value=0}
</div>
<!-- I tried to use both ways shown below to display the captured item -->
{$soco}
{$smarty.capture.soccerCats}
any idea why is this happening?
I don't think {capture} works inside {if} tags, and if does, I'd advise against it, for better code readability. Try something like this:
<div>
<!-- deal with category levels -->
{if empty($category_level)}
{assign var="category_level" value=1}
{else}
{math equation="x + 1" x=$category_level assign="category_level"}
{/if}
{foreach from=$categories item="category"}
{capture name="code"}
<ul>
<li class="{$category.name|htmlspecialchars}Cat">{$category.name|htmlspecialchars}<a class="mobileOnly"><i class="fa fa-angle-down fa-fw"></i></a>
{if !empty($category.children)}
<ul>
{assign var="categories" value=$category.children}
{if empty($category_level)}
{assign var="category_level" value=1}
{else}
{math equation="x + 1" x=$category_level assign="category_level"}
{/if}
{foreach from=$categories item="category"}
{if $category.level == $category_level && $category.is_visible == "Yes"}
<li>{$category.name|htmlspecialchars}</li>
{/if}
{/foreach}
{math equation="x - 1" x=$category_level assign="category_level"}
{assign var="category" value=0}
</ul>
{/if}
</li>
</ul>
{/capture}
{if (strstr($category.name, 'Soccer') != true)}
{$smarty.capture.code}
{else}
{$soccercats=$smarty.capture.code} {*Updated with #Borgtex's comment*}
{/if}
{/foreach}
</div>
{$soccercats}
The idea is that you capture everything and if the category is not 'soccer', you display the captured data; otherwise, you assign it to another capture, to use it in the end, outside the loop. The code assumes that there is a single soccer category, as you initially stated in your question.

Smarty foreach counter , reset after 3 element

I want to create foreach smarty loop with counter and 3 "if" conditions inside.
After my counter value is more than 3 I want to reset counter value and get back to first condition of If
This is my code
{foreach $itemscollection as $singleitem name=smartyloop}
{assign var="counter" value=$smarty.foreach.smartyloop.iteration}
{if $counter == 1}
<h1>I am the one</h1>
{/if}
{if $counter == 2}
<h1>I am second</h1>
{/if}
{if $counter == 3}
<h1>I am third</h1>
{/if}
{if $counter > 3}
{$counter = 1}
{/if]
{/foreach}
So for example If I have 4 elements to place into foreach output should look like
I am the one
I am second
I am third
I am the one
Now it's not working and i don't know why.
Can somebody please help me and tell how to resolve that problem ?
{assign var=counter value=1}
{foreach $itemscollection as $singleitem name=smartyloop}
{if $counter == 1}
<h1>I am the one</h1>
{/if}
{if $counter == 2}
<h1>I am second</h1>
{/if}
{if $counter == 3}
<h1>I am third</h1>
{/if}
{if $counter > 3}
{assign var=counter value=1}
{/if]
{$counter++}
{/foreach}
this might work
I know this is an old one but try to use counter as a custom function from smarty:
{foreach $itemscollection as $singleitem name=smartyloop}
{counter assign='pos'} {* assign counter to variable *}
{if $pos == 1}
<h1>I am the one</h1>
{/if}
{if $pos == 2}
<h1>I am second</h1>
{/if}
{if $pos == 3}
<h1>I am third</h1>
{counter start=0} {*reset counter*}
{/if}
{/foreach}
Had to go back to CMS Made Simple to make something related ;)
Try like
{if $counter%3 eq 0 && $counter gt 2}
{assign var=counter value=1}
{/if}
You can use {cycle} http://www.smarty.net/docs/en/language.function.cycle.tpl
{cycle name="counter" values="1,2,3"}
Or you could use the Modulus(%) operator http://php.net/manual/en/language.operators.arithmetic.php
{$counter = ($smarty.foreach.smartyloop.iteration % 3) + 1}
This solution is working
I dont't know why , maybe foreach checks conditions from last to first .
{foreach $blogscollection as $singleblog name=smartyloop}
{assign var="counter" value=$smarty.foreach.smartyloop.iteration}
{if $counter>3}
{assign var=counter value=1}
{/if}
{if $counter == 1}
<h1>I am the one</h1>
{/if}
{if $counter == 2}
<h1>I am the second</h1>
{/if}
{if $counter == 3}
<h1>I am the third</h1>
{/if}
{/foreach}
<?php
$array=array(' the ','hap',' pop' ,' grand'); // assume this is your array to pass in for each
$says=array(' the one','second',' third'); // store your word to appear
$count=0;
foreach ($array as $arr){
if($count == 3) $count=0;
print "<h1>I am $says[$count]<h1>";
$count++;
}
?>

Delete first element after if statement

Need to delete first element after all this statements, i try to add key=i to second foreach, and add {if $i!=0}, but it dont work for me, because i have multilevel system and after all if statements first $i is different for all pages.
{foreach from=$page.path item=e}
{assign var=element value=0}
{foreach from=$menu3 item=r}
{if $e.page_id==$r.page_id}{assign var=element value=$r}{/if}
{if $element._left < $r._left && $element._right > $r._right}
{if $r._level==$element._level+1 && $r._level==$page._level}
{$r.name}
{/if}
{/if}
{/foreach}
{/foreach}
P.S. Sorry for my English.
Add a name to you foreach and do something like this to get index
{foreach from=$items key=myId item=i name=foo}
{$smarty.foreach.foo.index} <!-- It will show index -->
{/foreach}
I assume you don't want to display first element in each of the menus you have, right?
{foreach from=$page.path item=e}
{assign var=first_skipped value=0}
{assign var=element value=0}
{foreach from=$menu3 item=r}
{if !$first_skipped}
{assign var=first_skipped value=1}
{else}
{if $e.page_id==$r.page_id}{assign var=element value=$r}{/if}
{if $element._left < $r._left && $element._right > $r._right}
{if $r._level==$element._level+1 && $r._level==$page._level}
{$r.name}
{/if}
{/if}
{/if}
{/foreach}
{/foreach}

PHP <li> loop listing the folders in the server

I'm learning PHP "on the go" as I edit a template for a website which I have to do at work, and I'm kinda lost. The original code looks like this:
<!-- start of top menubar -->
<table border="0" cellpadding="0" cellspacing="0" width="{$web_var_main_width}" align="center">
<tr style="background-color:#{$web_var_top_tabs_background};">
{php}
global $lang;
$this->assign('web_var_top_folder', $this->get_template_vars('web_var_top_folder_'.$lang));
{/php}
<td align="right" style="{if $web_var_top_tabs_image ne "" and $web_var_top_tabs_image ne 0}background:url(http://{$lang}.{$website_name}/{$RSwebPath}utilities/getScaledPicture.php?imageID={$web_var_top_tabs_image}&w={$web_var_top_tabs_image_x}&h={$web_var_top_tabs_image_y}&adj=d) top left repeat-y;{/if}background-color:#{$web_var_top_tabs_background_right};">
{if $folders_structure|#count gt 0}
{if $web_var_top_folder gt 0}
{section name=findtop loop=$folders_structure}
{if $folders_structure[findtop].key eq $web_var_top_folder}{assign var="top_menu" value=$folders_structure[findtop].childs}{/if}
{/section}
{if $top_menu|#count gt 0}
<table border="0" cellpadding="0" cellspacing="0" align="right">
<tr>
{if $web_var_top_font_size eq "small"}
{assign var="web_var_top_font_size" value="10px"}
{elseif $web_var_top_font_size eq "medium"}
{assign var="web_var_top_font_size" value="12px"}
{elseif $web_var_top_font_size eq "large"}
{assign var="web_var_top_font_size" value="14px"}
{elseif $web_var_top_font_size eq "extra large"}
{assign var="web_var_top_font_size" value="16px"}
{/if}
{section name=mytopsec loop=$top_menu}
<td width="5"></td>
{strip}
{if $top_menu[mytopsec].key eq $folders_selected[1]}
{assign var="topsel" value="1"}
<td bgcolor="#{$web_var_top_selected_tabs_color}" style="padding:6px 30px"><span style="font-family:{$web_var_top_font_family}; color:#{$web_var_top_font_color}; font-size:{$web_var_top_font_size}; font-weight:{$web_var_top_font_weight}; font-style:{$web_var_top_font_style}; text-decoration:none">{$top_menu[mytopsec].name}</span></td>
{else}
<td bgcolor="#{$web_var_top_tabs_color}" onMouseOver="this.style.backgroundColor='#{$web_var_top_tabs_hover}'; style.cursor='pointer'; style.cursor='hand'" onMouseOut="this.style.backgroundColor='#{$web_var_top_tabs_color}'" style="padding:6px 30px">{$top_menu[mytopsec].name}</td>
{/if}
{/strip}
{/section}
</tr>
</table>
{/if}
{/if}
{/if}
</td>
</tr>
<!-- end of top menubar -->
I have to send a folder ID which is the one the code scans into and shows all its childs.
And the function which scans the folders and lists them as menu items is this one:
<?
include_once "folderFunctions.php";
global $lang;
$global_deep=0;
$this->assign("folder_structure",getFolderChilds(0,$_SESSION["rs_domain_id"],$lang,"WEB",0,$global_deep));
$this->assign("folder_deep",$global_deep);
?>
Which uses the funcion GetFolderChilds from folderFunctions.php:
function getFolderChilds($identification,$website,$lang,$type,$local_deep,&$global_deep){
$child_list=array();
$childs = #mysql_query("SELECT `HB_IDENTIFICATION`,`HB_TITLE`,`HB_DESCRIPTION`,`HB_IMAGE_IDENTIFICATION`,`HB_LINK` FROM `hb_folders` WHERE `HB_PARENT_IDENTIFICATION` = ".$identification." AND `HB_DELETED`=0 AND `HB_PUBLISHED`=1 AND HB_WEBSITE_ID=".$website.(($type=='image')?(''):(" AND HB_LANGUAGE_ID='".$lang."'"))." AND HB_TYPE='".$type."' ORDER BY HB_ORDER");
$local_deep++;
if($local_deep>$global_deep&&#mysql_num_rows($childs)>0) $global_deep=$local_deep;
while($child = #mysql_fetch_assoc($childs)){
//$auxPermissions=getPermissions($_SESSION["rs_user_login"],$_SESSION["rs_user_pass"],$website,$child['HB_IDENTIFICATION'],'FOLDER');
//if($auxPermissions['read']==1){
$child_list[]=array("key"=>$child['HB_IDENTIFICATION'], "name"=>$child['HB_TITLE'], "desc"=>$child['HB_DESCRIPTION'], "image"=>$child['HB_IMAGE_IDENTIFICATION'], "link"=>$child['HB_LINK'], "childs"=>getFolderChilds($child['HB_IDENTIFICATION'],$website,$lang,$type,$local_deep,$global_deep));
//}
}
return $child_list;
}
And its output is something like this (tab changes color when mouse is on it, and so):
Well, that's what I figured out until now.
The thing is that I want to do a menu with these PHP functions, that is, creating the folders in the server and doing a loop which scans and shows them in my menu.
The thing is, that code uses tables, and has a lot of things which I don't need, such as image tabs and so (I just want to have a text menu with no images).
My question is, how can I implement the function to get the folders and list them not in a table, but in a list, so the output is something similar to this (I want to keep it as simple as posible in order to understand what is being done in any point)?
<header>
<ul class="navigation0">
<li>start</li>
<li>about us</li>
<li>contact</li>
</ul>
</header>
Which shows this:
Thanks a lot.
I believe I've solved it:
{php}
global $lang;
$this->assign('web_var_top_left_folder', $this->get_template_vars('web_var_top_left_folder_'.$lang));
{/php}
{if $folders_structure_left|#count gt 0}
{if $web_var_top_left_folder gt 0}
{section name=findtopleft loop=$folders_structure_left}
{if $folders_structure_left[findtopleft].key eq $web_var_top_left_folder}{assign var="top_left_menu" value=$folders_structure_left[findtopleft].childs}{/if}
{/section}
{if $top_left_menu|#count gt 0}
{if $web_var_top_font_size eq "small"}
{assign var="web_var_top_font_size" value="10px"}
{elseif $web_var_top_font_size eq "medium"}
{assign var="web_var_top_font_size" value="12px"}
{elseif $web_var_top_font_size eq "large"}
{assign var="web_var_top_font_size" value="14px"}
{elseif $web_var_top_font_size eq "extra large"}
{assign var="web_var_top_font_size" value="16px"}
{/if}
<ul class"leftmenu">
{section name=mytopsecleft loop=$top_left_menu}
{strip}
{if $top_left_menu[mytopsecleft].key eq $folders_selected[1]}
{assign var="topselleft" value="1"}
<li><span style="font-family:{$web_var_top_font_family}; color:#{$web_var_top_font_color}; font-size:{$web_var_top_font_size}; font-weight:{$web_var_top_font_weight}; font-style:{$web_var_top_font_style}; text-decoration:none">{$top_left_menu[mytopsecleft].name}</span></li>
{else}
<li onMouseOver="style.cursor='pointer'; style.cursor='hand'>{$top_left_menu[mytopsecleft].name}</li>
{/if}
{/strip}
{/section}
</ul>
{/if}
{/if}
{/if}

Categories