I have this results after foreach on the template. But how can stop foreaching the same values and show only one?
<ul>
{foreach from=$names item=v name=thenames}
<li>{$v.names}/<li>
{/foreach}
</ul>
If it's a simple key->value array, you can use array_unique in your php file to process the array before sending it to smarty. You also probably can call it inside the template with $names|array_unique
If all the duplicates are one after another (i.e. a,a,a,b,b,c,c,c), you can try using a variable to store the previous value, so it only shows the first:
{assign var="previous" value=""}
{foreach from=$names item=v name=thenames}
{if $previous!=$v.names}
<li>{$v.names}/<li>
{/if}
{assign var="previous" value=$v.names}
{/foreach}
If not, I recommend preprocessing the array in php or using smarty 3.
Related
I use this code in the product.tpl file to show product categories:
{foreach from=Product::getProductCategoriesFull($product.id_product) item=cat}
{$cat.name},
{/foreach}
The result is similar to this:
Name: Lifts, Machines, Gearless,
The question is:
How can I choose what element I want to show (Lifts only, Machines only or Gearless only)??
I need to show one element from the foreach element position.
You should pass to your TPL only the category you want to display (calculation should be done in PHP file, not Smarty).
If you wanna go the dirty awy you can just
{break}
after first element display,
or if you want to display a certain category based on its name
just edit your code to something like :
{foreach from=Product::getProductCategoriesFull($product.id_product) item=cat}
{if $cat.name == "Lifts"}
{$cat.name}
{/if}
{/foreach}
Just use a if statement?
{foreach from=Product::getProductCategoriesFull($product.id_product) item=cat}
{if $cat.name == 'Machines'}
{$cat.name},
{/if}
{/foreach}
{assign var="loop_middle" value=Product::getProductCategoriesFull($product.id_product)|#count/2}
{foreach from=Product::getProductCategoriesFull($product.id_product) item=cat name=foo}
{if $smarty.foreach.foo.last || $smarty.foreach.foo.iteration == $loop_middle|ceil}
{$cat.name}
{/if}
{/foreach}
This will let you display last element of your array (last category):
$smarty.foreach.foo.last
This will let you display middle element of your array (middle category):
$smarty.foreach.foo.iteration == $loop_middle|ceil
Sorry about the difficulty for me to make the title much clearer. I'll explain as much as I can.
I use Rails as the backend (API), and AngularJS as the frontend.
I got several article_ids that have been liked(thumb up) from articleCtrl, named $scope.article_has_liked (it's an array contains several article_ids, like [24,45,55] ), just like below, :
articleCtrl.js.coffee
$http.get(url).success((data)->
console.log(data)
$scope.articles = data.articles
$scope.topic = data.topic
$scope.article_has_liked = data.article_has_liked
)
And I pass these article_ids ($scope.article_has_liked) to the show.html, in order to use "ng-if" to conduct a judgement, just like below:
Show.html
<div ng-if="article_has_liked.include?(article.id)">
<button class="btn btn-link" ng-click="likeItOrNot(article.id, topic.id)">
<span class="glyphicon glyphicon-star"></span>
</button>
</div>
<div ng-if="article_has_liked.exclude?(article.id)">
<button class="btn btn-link" ng-click="likeItOrNot(article.id, topic.id)">
<span class="glyphicon glyphicon-star-empty"></span>
</button>
</div>
Here comes the problem !
I'd like to use .include? method in Ruby to determine if the article.id is included by the article_ids that have been liked. If it is liked, I'll give it a solid star. But I found that the Angular seems not to accept the usage, and it returned the error just like below:
Error: Syntax Error: Token 'undefined' expected : at column NaN of the expression [article_has_liked.include?(article.id)] starting at [article_has_liked.include?(article.id)].
throwError#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:6672:1
ternary#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:6827:9
_assignment#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:6800:16
expression#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:6796:12
_filterChain#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:6762:16
statements#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:6742:25
parser#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:6661:13
$ParseProvider/this.$get</<#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:7282:1
compileToFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:9215:16
$RootScopeProvider/this.$get</Scope.prototype.$watch#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:8547:19
ngIfDirective</<.compile/<#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:14677:9
nodeLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4960:13
compositeLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4539:15
compositeLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4554:13
compositeLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4554:13
compositeLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4554:13
compositeLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4554:13
compositeLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4554:13
publicLinkFn#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:4456:30
ngRepeatAction#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:15463:15
$watchCollectionAction#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:8718:11
$RootScopeProvider/this.$get</Scope.prototype.$digest#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:8812:21
$RootScopeProvider/this.$get</Scope.prototype.$apply#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:9013:13
done#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:10266:34
completeRequest#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:10450:7
createHttpBackend/</xhr.onreadystatechange#http://localhost:3000/assets/angular.self-cdfe10db265380c82ec938d307fce2720dc9fb9d8cfa21c78928031af124e282.js?body=1:10405:1
<!-- ngIf: article_has_liked.include?(article.id) -->
So I want to ask if there is any conditional statement which has similar meaning to .include? that I can use in AngularJS "ng-if", or there is any better way for me to conduct this judgement?
Thanks everyone for helping me this confusing question!
That is a JavaScript relating question, not AngularJS. But may that answer your question:
Often you will need to check whether an array contains a certain item. You can do this by using the indexOf() method. If the code does not find the item in the list, it returns a -1.
var article_has_liked = [24,45,55];
if(article_has_liked.indexOf(99) == -1){
alert("data not found");
}
Not sure but you can try something:
<div ng-if="article_has_liked.indexOf(article.id) != -1">
Note: This above condition is to check for include. If it include your article.id in article_has_liked then only execute that block. If you want to check exclude then you can simply use == instead != I hope it works for you.
ng-if="article_has_liked.include?(article.id)"
update to this one:
ng-if="article_has_liked.include?(article.id):false value here"
<span id='sitemap'>
{#footer.sitemaps}
<a id="{id}" href="{url}">{#pre type="content" mode="json" key="footer.{id}"/}</a>
{/footer.sitemaps}
</span>
In the code, {id} is a property of one element in footer.sitemaps. I want Makara to get the key value dynamically using {id}. May I know how to do that?
See the discussion around this makara issue: https://github.com/krakenjs/makara/issues/36
Check this: https://github.com/mikesparr/Kraken_Example_i18n_Helper
You can use #bundleString helper rather than #pre.
So, you can use something like {#bundleString key="footer.{id}" bundle="your_data_properties_file name"}
You can do that by using the {#provide} tag. Here is an example using yours:
{#provide}
{#footer.sitemaps}
<a id="{id}" href="{url}">{footerMap[id]}</a>
{/footer.sitemaps}
{:footerMap}
{#pre type="content" mode="json" key="footer"/}
{/provide}
If your properties file looked like
footer.key1=SomeVal
footer.key2=AnotherVal
and your footer.sitemaps data object looked like
{
id: 'key1',
href: 'http://my/url
}
The result of running this would be
<a id="key1" href="http://my/url">SomeVal</a>
I`m trying to create a widget for dashing (http://shopify.github.io/dashing/) for displaying 4 values:
value1
value2
value3
value4
I have copied the contents of the text widget and added the following to the widget.html
<h3 data-bind="text | raw"></h3>
<p class="more-info" data-bind="moreinfo | raw"></p>
<p class="value1" data-bind="value1"></p>
<p class="value2" data-bind="value2"></p>
<p class="value3" data-bind="value3"></p>
<p class="value4" data-bind="value4"></p>
<p class="updated-at" data-bind="updatedAtMessage"></p>
When I add this widget to my dashboard using:
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="mywidget" data-view="mywidget" data-title="Grupserhs" data-text="Systems Dashboard" data-moreinfo="Hello"></div>
</li>
Yet I have a blank page in my dashboard.
What would be the correct way to create a widget that will only receive pushed data?
Thanks in advance.
Actually use "list" widget for this. Look at the 'buzzwords.rb' file for an idea.
Do you have a coffeeScript file that defines your widget class and extends Dashing.Widget? You don't need anything else in there to start, but that is where your widget is defined.
Also, do you have a job pushing data to this widget id "mywidget"? If not, look in the jobs folder, same level as widgets folder to get an idea, basically a Rufus scheduler task to pump data to your widgets. ..and don't forget to check the css for your widget..
From the current information, in the dashboard, it shall using like
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="mywidget" data-view="mywidget" data-title="Grupserhs" data-text="Systems Dashboard" data-moreinfo="Hello" data-value1="first value" data-value2="this is value2" data-value3="value3" data-value4="last value" ></div>
</li>
The data-bind="value1" shall be mapped into dashboard like data-value1
It may have other problems, like putting those widget in separate folder, your css format. Please provide more detail file list for reference if it can't solve it.
Ok, so I have this code.
{foreach $listings as $id => $listing name=listing}
{if $smarty.foreach.listing.iteration is div by 4}
ADSENSE CODE
{/if}
{/foreach}
What this does is it outputs Google adsense code every 4 items.
As you will be aware, Google adsense only allows 3 ads per page so I require it to break after showing the ad 3 times.
After many fruitless Google searches, I am stumped!
Please help,
Regards.
as far as i can see here
you can use
{break}
and it should work
also, you can have a counter and
{foreach $listings as $id => $listing name=listing}
{if $smarty.foreach.listing.index <= 12}
{if $smarty.foreach.listing.iteration is div by 4}
ADSENSE CODE
{/if}
{/if}
{/foreach}
Ok, so after looking at the code I had an epiphany.
I only want to show the ad 3 times so I did this and it works like a charm.
{foreach $listings as $id => $listing name=listing}
{if $smarty.foreach.listing.index == 4}
ADSENSE CODE
{/if}
{if $smarty.foreach.listing.index == 8}
ADSENSE CODE
{/if}
{if $smarty.foreach.listing.index == 12}
ADSENSE CODE
{/if}
{/foreach}