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
Related
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"
I have a Content Repository which contains 2 sections, Career Categories and Branches.
I have create for each one a filter, below you can find the code for Career categories. This is working fine. Now I want to display the amount of visible content nodes for each item of the filter.
The content node contains 2 properties which are content pickers set to only select one.
Property alias for the Career category picker is function.
This doesn't work which give me always 0, but I have created one content page. What am I missing here?
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#*
This snippet takes all of the career categories to create a filter
*#
#{
// Take the content repository node
IPublishedContent contentRepository = Umbraco.ContentAtRoot().DescendantsOrSelf("ContentElements").FirstOrDefault();
// Take the career categories node
var careerCategorieRep = contentRepository.Children.Where("DocumentTypeAlias == \"ucCareersCategoryRepository\"").FirstOrDefault();
// Take the careers list content node
IPublishedContent careersList = Umbraco.ContentAtRoot().DescendantsOrSelf("CareersList").FirstOrDefault();
}
<ul class="col-md-12 col-sm-6 aside-widget-container">
<li class="widget">
<div class="title">
<h3>Beroep</h3>
</div>
<ul class="menu">
#* // Loop over the categories *#
#foreach (var careerCategorie in careerCategorieRep.Children.Where("Visible").OrderBy("Name").ToList())
{
// Here I need to filter on the career category to get the amount of visible nodes in the content
var count = careersList.Children.Where("Visible && function == " + careerCategorie.Id).Count();
<li>#careerCategorie.Name<i class="fa fa-angle-right"></i></li>
}
</ul>
</li>
</ul>
UPDATE
The problem is in this line of code:
var count = careersList.Children.Where("Visible && function == " + careerCategorie.Id).Count();
I need to get the amount of visible pages which has a certain property value, eg. content picker with Id of the career category.
First of all, you should probably be using TypedContentAtRoot and not ContentAtRoot. TypedContent is retrieved from the Umbraco.config xml cache rather than the database so should be faster.
From your explanation I think you are saying that this line is the problem
var careerCategorieRep = contentRepository.Children.Where("DocumentTypeAlias == \"ucCareersCategoryRepository\"").FirstOrDefault();
Change it to
var contentRepository.Children.FirstOrDefault(n => n.DocumentTypeAlias == "ucCareersCategoryRepository");
That should do it.
Okay my other answer has some good advice but I think your problem may be something else.
if you are searching for Visible nodes this relies on a property on your document type called umbracoNaviHide. The property should be of a true/false datatype.
You have to add this property to the doc type and then set it to true (checked) if you wish to hide a node.
Then you can use either
myNode.Children.Where("Visible")
OR (just to show the way in which you can write lambda filter expressions)
myNode.Children.Where(x => x.IsVisible())
OR (this last just to illustrate that umbracoNaviHide is just a property on a doc type)
myNode.Children.Where(x => x.GetPropertyValue<string>("umbracoNaviHide")=="1")
Ok I have found the solution:
I needed to surround the Id with quotes because its stored as a string and not as a int.
var count = careersList.Children.Where("Visible && function == \"" + careerCategorie.Id + "\"").Count();
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.
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}
I am trying to do the following:
#foreach(var p in #Model.line_products){
<img class="small_img_#Model.line_products[i].short_name" src="/Content/images/#Model.line_products[i].image_name" />
}
Which isn't working, it renders the text just the way it is, not recognizing the '#'. I found this other post in Stackoverflow, which suggests adding parenthesis in the following way:
#foreach(var p in #Model.line_products){
<img class="small_img_(#Model.line_products[i].short_name)" src="/Content/images/#Model.line_products[i].image_name" />
}
Using this workaround, I get that my id is rendered as small_img_(MODEL ATTRIBUTE). Isn't there a workaround which doesn't require adding specific characters? (such as the parenthesis).
You have more errors than a simple undercore problem here. You cannot use #Model inside your if. You are already in a # block. Simply use #foreach(var p in Model.line_products).
Plus, the way you wrote the parenthesis, they will get rendered. What you want is
small_img_#(Model.line_products[i].short_name)
Put the parenthesis after the # instead of before:
class="small_img_#(Model.line_products[i].short_name)"
I sometimes put a couple of Guids in the id of an element and an underscore separator doesn't work.
There are two ways around this. First use the entity code _ instead and secondly just use a hyphen.
<input id="chk_#classLeader.ClassLeader_#ing.Ingredient.Guid" type="checkbox" class="chk_Done form-check">
<input id="chk-#classLeader.ClassLeader-#ing.Ingredient.Guid" type="checkbox" class="chk_Done form-check">
This is because I want to grab out the Guid's when the check box is clicked with some JQuery like this:
$(".chk_Done").click(function () {
var obj =[];
const itemId = ($(this).attr("id"));
const myArray = itemId.split("_");
var ClassLeaderGuid = myArray[1], IngredientGuid = myArray[2];