问题
Google Blogger has implemented a new set of Lambda expression operators for its template language. See: https://blogger.googleblog.com/2016/05/more-custom-template-flexibility.html and https://productforums.google.com/forum/#!topic/blogger/l3phi8bscGY .
The example code given (the b:if/ amended) is:
<!-- Show a Flower image if the post has the label flower -->
<b:if cond='data:post.labels any (l => l.name == "Flower")'>
<img src=’/img/flower.jpg’ />
</b:if>
I can't figure out how to get this to work in a template. Would someone please provide some working code I could drop in to a template and see it working.
UPDATE: This seems to work. But how, or can I, remove the loop?
<b:section class='Test1' id='Test1' maxwidgets='' showaddelement='no'>
<b:widget id='Blog2' locked='true' title='Blog Posts' type='Blog' version='1' visible='true'>
<b:includable id='main'>
<b:loop values='data:posts' var='post'>
<h1>Post found</h1>
<b:if cond='data:post.labels any (label => label.name == "flower")'>
<h1>Flower!</h1>
</b:if>
</b:loop>
</b:includable>
</b:widget>
</b:section>
For example, if I remove the loop, and replace it with :
<b:if cond='data:posts any (p => p.title != "bob")'>
<h1>Post found</h1>
</b:if>>
Only one post is found, when I have several posts none of which are titled bob! I have tried switching the lambda operator from any to filter with no change.
回答1:
The solution to my problem
Stupid of me, if I expect to be able to use a loop I need to specify a loop:
<b:loop values='data:posts filter (p => p.id != 0)' var='post'>
<h1>Post found: <data:post.title/></h1>
</b:loop>
How to use Blogger Lambda Operators
For those coming here trying to find help I recommend the following article which explains how to use Lambda expressions quite comprehensively: http://www.bloggerever.com/2016/05/what-are-exactly-bloggers-lambda.html and is based on https://productforums.google.com/forum/#!topic/blogger/l3phi8bscGY.
In essence there are 7 Lambda operators
- any
- all
- none
- count
- filter
- map
- first
Each of which can be used either inside an if or loop conditional statement. Some untested sample code follows to help get you started.
The any operator returns true if any items in the Lambda return true, so for example, the following code would return true if a post had a label labela or labelb associated with it:
<b:if cond='data:post.labels any
(l => l.name in {"labela","labelb"})'>
...Code here...
</b:if>
all would return true if it had both labela and labelb associated with it:
<b:if cond='data:post.labels all
(l => l.name not in {"labela","labelb"})'>
...Code here...
</b:if>
none would return true if it had neither labela and labelb associated with it:
<b:if cond='data:post.labels all
(l => l.name not in {"labela","labelb"})'>
...Code here...
</b:if>
count would return 0, 1 or 2 depending on whether a post had neither labela or labelb associated with it, or just labela or both labela and labelb
<b:if cond='data:post.labels count
(l => l.name not in {"labela","labelb"})'>
...Code here...
</b:if>
filter will return an array and requires a loop. The example below would print out the title of each post unless it had an id of 0 (which i don't is possible!)
<b:loop values='data:posts filter (p => p.id != 0)' var='post'>
<h1>Post found: <data:post.title/></h1>
</b:loop>
first like filter, but will return the first match only.
<b:loop values='data:posts first(p => p.timestamp == "4.2.09")' var='post'>
<h1>Post found: <data:post.title/></h1>
</b:loop>
map returns an array set containing each result from the Lambda. The code below would display labels in a h1 tag with >> prepended.
<b:loop values='data:post.labels map (l=> ">>" + l.name)' var='label'>
<h1><data:label/></h1>
</b:loop>
A final note: the article linked to suggests the Lambda's may only be applied to post, label and comment elements. It certainly works with the first two but I haven't tried it with comments.
来源:https://stackoverflow.com/questions/37436554/how-to-use-google-blogger-lambda-operators