Can anyone tell me how to use dynamic variables in smarty foreach loop. I am trying to create a module in prestashop and m very close to get it done.
here's my code:
//file name index.php
foreach( $subCategories as $s )
{
$foo = intval($s['id_category']);
$k = new Category($foo);
$var1 = "subSubCategories.$foo";
$var1 = $k->getSubCategories(1);
$smarty->assign(array('foo'.$foo => $var1));
}
//file name:index.tpl
{assign var=foo value=$foo$cat}
//where $cat is a variable that counts the number of categories
{if isset($foo) AND $foo}
{foreach from=$foo item=subCategories name=homesubCategories}
<p>{$subCategories.name}</p>
{/foreach}
{else}
<p>{l s='test failed'}</p>
{/if}
I've exhausted all of my resources and knowledge and feeling quite helpless at this moment. so plz help me out.
I am trying to create dynamic variables ('foo'.$foo i.e. foo1, foo2, and so on) depending on the number of sub-categories. I think m successful up to this point. Now moving on to the tpl file, here I want to access the dynamically created variable (foo2, foo3 etc.) using foreach. Now if I am doing this: {assign var=foo value=$foo3} I succeed in fetching the values from this subcategory using the same foreach loop. But when I do this: {assign var=foo value=$foo$catx} (where $catx stores the values for category id) it fails. Please help.
I use such code in section loop (for Smarty 2):
{section name=buildings loop=7 start=1 step=1 max=7}
<tr>
{assign var=part_number value="part`$smarty.section.buildings.index`_number"}
<td class="number">
<input class="number xshort" name="part{$smarty.section.buildings.index}_number" value="{$data.$part_number}" type="text">
</td>
</tr>
{/section}
As you can see, there are a creation of dynamic variable part_number (see backticks in value block). And then, you can use it as value="{$data.$part_number}".
Your $smarty->assign() call is incorrect; you've only got one parameter being sent to it, but it needs two parameters (the variable name, followed by the value). Based on your template code (looping through variable $foo), your loop should be something like this in PHP:
//file name index.php
$subcats = array();
foreach($subCategories as $s) {
$foo = intval($s['id_category']);
$k = new Category($foo);
$subcats[$foo] => $k->getSubCategories(1);
}
$smarty->assign('foo', $subcats);
Then it also looks like you're not using the Smarty {foreach} quite properly either. You're declaring the name attribute, of the foreach loop, but then not using it properly. Assuming $k->getSubCategories(1) returns a string, the smarty code would just have to be:
{foreach from=$foo item=subCategories}<p>{$subCategories}</p>{/foreach}
If $k->getSubCategories(1) returns an array with a 'homesubCategories' element (which is what I think you're trying to get at with your Smarty code), you still don't need the 'name' value on the foreach. You'd then just do:
{foreach from=$foo item=subCategories}<p>{$subCategories.homesubCategories}</p>{/foreach}
With $foo = intval($s['id_category']); you defined $foo as an integer.
Then you concat the string with $smarty->assign(array('foo'.**$foo** => $var1));
Correct is:
$foo = $s['id_category'];
$smarty->assign(array('foo'.$foo => $var1));
Dynamically named variables are generally a very bad design choice, making everything much more difficult than it needs to be.
If you have a set of elements you need to loop over or index into, put them in an array; then you don't need to do any magic assignments, as you can use normal foreach loops or array key access:
//file name index.php
// Build the array first, then assign it to Smarty at the end
$foo_array = array();
foreach($subCategories as $s)
{
$foo = intval($s['id_category']);
$k = new Category($foo);
// This line is redundant as you over-write on the following line:
// $var1 = "subSubCategories.$foo";
$var1 = $k->getSubCategories(1);
$foo_array[ $foo ] = $var1;
}
// Assigning one variable, so just pass name and value to $smarty->assign()
$smarty->assign('foo_array', $foo_array);
//file name:index.tpl
{* Look for the entry in the outer array with key "$cat", then loop over it *}
{foreach from=$foo_array[$cat] item=subCategories}
<p>{$subCategories.name}</p>
{/foreach}
it's possible to call variable dynamically created in template with this statement:
if for example $index = 2
{$foo{$index}}
then this will call variable with name {$foo2}
Related
First of all thanks for your time on my issue.
Second sorry if this is a duplicate, I legit searched for 3 days on and off and didn't find answer to my particular situation.
Visual on the error obtained
This first line transforms an array's values into a string of index(es)
$path = self::extract_path($path);
After extraction $path becomes a string with a format similar to['key1']['key2']
Here I test if one valuable element (ondemand) is found within that Keys string, so far so good.
if( $path !== FALSE && strpos($path, $element) !== FALSE){
$var_dim_str = 'coupon' . $path . '[recurrence]';
As a self-proofing, I hard-coded one of my specific scenario element and it does exist so my issue is not really non-initialization of my variable as most other topic were suggesting.
var_dump($coupon['item']['ondemand']['recurrence']);
My issue lies here, I get "ErrorException [ Notice ]: Undefined variable: coupon[item][ondemand][recurrence]"
$recurrence = $$var_dim_str;
[...]
Here are my var_dump output:
These are my indexes as an array they get extracted to reconstruct the variable's string', I have some variable-dimension arrays that gets called so the dimension depth might not always be of fixed value, hence why I have to dynamically test this.
1- $path, before being extracted
[...]\modules\payment\classes\Helper\Payment.php:290:
array (size=2)
0 => string 'item' (length=4)
1 => string 'ondemand' (length=8)
2- We see here that (['item']['ondemand']['recurrence'] => 3) exists
[...]\modules\payment\classes\Payment\Cart.php:266:
array (size=1)
'item' =>
array (size=3)
'ondemand' =>
array (size=14)
[...]
'recurrence' => string '3' (length=1)
[...]
3- My var_dump above is outputting it properly.
[...]\modules\payment\classes\Payment\Cart.php:270:string '3' (length=1)
**So, my conclusion is that PHP doesn't really appreciate my 'built' variable but there has to be some way to make this logic work... any pointers on this would be really appreciated. **
The issue does lie with $$var_dim_str. What the $$ does is resolve $$variableName to be the variable name contained in $variableName. It basically holds a reference to another variable based on the variable's name. From the PHP site:
A variable variable takes the value of a variable and treats that as the name of a variable. In the above example, hello, can be used as the name of a variable by using two dollar signs. i.e.
So ...
// some variables
$name = 'Ellan' ;
$site = 'Stack Exchange' ;
$tags = 'PHP-7, Variables' ;
// we want $site
$variableName = 'site' ;
echo $$variableName ;
// we want $tags
$variableName = 'tags' ;
echo $$variableName ;
The code above will produce:
Stack Exchange
PHP-7, Variables
When you assign a value to $var_dim_str:
$var_dim_str = 'coupon' . $path . '[recurrence]';
$var_dim_str does not hold the name of a variable. It contains the a string.
Are you sure you want to use $$ in this instance? Maybe you really want to use:
$recurrence = $var_dim_str;
Following this question. There is something wrong, when using CDbMigration::update() inside foreach loop.
This code does not work correctly:
//This is executed inside Yii migration, so $this is CDbMigration.
foreach($idMap as $menuId=>$pageId)
{
$this->update
(
'menus_items',
array('link'=>'/content/show?id='.$pageId),
array('id = '.$menuId)
);
}
For each item in $idMap value of $pageId is always the same and equals value of last item in $idMap array. Therefore, every menu item points to the same URL.
This code works like a charm:
foreach($idMap as $menuId=>$pageId)
{
$sql = "UPDATE `menus_items` SET link = '/content/show?id=".$pageId."' WHERE id = ".$menuId."; ";
Yii::app()->db->createCommand($sql)->execute();
}
For each item in $idMap value of $pageId is always different and equals value of current item in $idMap array. Therefore, every menu item points to correct URL.
The same goes, when executing all statements in one SQL query:
$sql = '';
foreach($idMap as $menuId=>$pageId)
{
$sql .= "UPDATE `menus_items` SET link = '/content/show?id=".$pageId."' WHERE id = ".$menuId."; ";
}
Yii::app()->db->createCommand($sql)->execute();
Again, everything is OK.
Why using CDbMigration::update() fails, while direct SQL execution works like a charm?
I don't think you are providing the criteria parameter properly # array('id = '.$menuId)
. You should use a string if you want to send it like that, putting it in an array presumes you are mapping out the conditions in a key => value pair. Also you should be wrapping the value constraint in quotes id = "$menuId".
I have a helper that loops through jason data till a given value and sends the data back to the template.I also want to show at what location the data is present (the index), is there any way where in i can return the Index value along with the data?
Handlebars.registerHelper('print_range', function(items,count,options)
{
var out = "";
for(var i=0, l=items.length; i<count; i++)
{
out = out + options.fn(items[i]);
}
return out;
});
<script id="template" type="text/x-handlebars-template">
{{#print_range options "2"}}
<h1>index</h1> // this index should correspond to i in the helper function
<h2>{{optionID}}{{nextID}}</h2>
{{/print_range}}
</script>
Thanks in advance.
Handlebars.registerHelper('print_range', function(items,count,options)
{{#print_range options "2"}}
Not sure 100% what you're asking, but i do see a problem in your code. You specify 3 parameters in the function, but only give it 2 in your statement call to the helper.
{{#print_range options "2"}}
^ fn name ^items ^ count
Where's the value for your options variable? In handlebars, the parameters for the function go in order after the helper name you are calling
I would like to know if it is possible to construct name of variable into velocity dynamically.
i.e. lets say I've 6 variables into velocity template [name1, name2, name3 .. name6] I would like to output them.
So I'm looking in something like:
#foreach ( $counter in [1..6] )
${name${counter}}
#end
is it possible somehow?
It is possible using the #evaluate directive:
#evaluate ('$name1')
#set ($d = '$')
#foreach ($i in [1..6])
#set ($varName = "${d}name${i}")
#evaluate($varName)
#end
You could construct a map and build the names of the keys to retrieve the values you want:
#set( $map = {"${name}1":'value1', "${name}2":'value2'} )
#foreach ( $counter in [1..6] )
#set( $key = "${name}$counter" )
$map.get(${key})
#end
Here is a trick to set velocity variable with dynamic name.
If you manage to tune velocity context beforehand in java code like this:
VelocityContext context = new VelocityContext(paramsMap);
context.put("all", paramsMap);
then it would be possible to define dynamic vars in template like this:
#set($dynamicDef = "varName=varValue")
#set($dynamicName = $dynamicDef.substring(0, $dynamicDef.indexOf('=')))
#set($dynamicValue = $dynamicDef.substring($dynamicDef.indexOf('=')).substring(1))
## create var with dynamic name
$all.put($dynamicName, $dynamicValue)
and use them later like this:
#if ($varName)
varName=$varName ## prints varName=varValue
#end
I need a wordpress loop that for every post checks a meta numeric variable previously assigned to each of the taxonomies of the post and returns the sum of these meta variables.
To do so, I think I need a dynamic variable name for the total. I mean something like:
variablerelatedtopost = metataxonomy1 + metataxonomy2 + ... + metataxonomyn
echo variablerelatedtopost
How can I do that? Is it possible to generate a dynamic numeric variable via loop? and HOW can I refer to it in a general way, without adressing it with its name?
Thanks everyone! And sorry for possible English mistakes :P
EDIT: I just realized the code by Alex is not what I wanted. I need a variable which changes name at every post and which value is always = 0. Is there a solution?
can you not just add a counter to your loop like this?
//Total should start # 0 before the loop
$total = 0;
// The Query
$the_query = new WP_Query($args);
// The Loop
while ( $the_query->have_posts() ) : $the_query->the_post();
$amount = get_post_meta($post->ID, 'the_meta_data_field', true);
$total = $total + $amount;
endwhile;
//echo total
echo $total;
I found the solution to my problem: an array which increases its lenght at every cicle of the loop. I know it's simple but since I'm just a beginner it took me a while to think about it. I post the code here so maybe it can help someone (and if you find bugs or have improvements, please tell me)
//Before the loop, empty array
$totale = array();
// WP Loop
while ( $loop->have_posts() ) : $loop->the_post();
$totale[] = 0;
$indice = (count($totale)) - 1;
// $termvariable was previously set up as a term meta value
if( has_term( 'numberofterm', 'nameoftaxonomy' ) ) {
$totale[$indice] = $termvariable + $totale[$indice];
}