我正在尝试编写以下内容,如果条件不流畅,但它不能正常工作。
条件 作为for循环的一部分,我想检查项目是第一个还是第4个,第8个等等
我认为以下内容可行,但它会显示每次迭代的代码。
<f:if condition="{logoIterator.isFirst} || {logoIterator.cycle % 4} == 0">
我已经设法让它使用嵌套if但只是感觉错了两次使用相同的代码段并且周期检查使用<f:else>
代替== 0
<f:if condition="{logoIterator.isFirst}">
<f:then>
Do Something
</f:then>
<f:else>
<f:if condition="{logoIterator.cycle} % 4">
<f:else>
Do Something
</f:else>
</f:if>
</f:else>
</f:if>
答案 0 :(得分:18)
TYPO3 v8
更新了TYPO3 v8的答案。这引自克劳斯的答案如下:
使用当前情况更新此信息:
在TYPO3v8及更高版本上,支持以下语法 完全符合您的使用案例:
<f:if condition="{logoIterator.isFirst}"> <f:then>First</f:then> <f:else if="{logoIterator.cycle % 4}">n4th</f:else> <f:else if="{logoIterator.cycle % 8}">n8th</f:else> <f:else>Not first, not n4th, not n8th - fallback/normal</f:else> </f:if>
此外还支持这样的语法:
<f:if condition="{logoIterator.isFirst} || {logoIterator.cycle} % 4"> Is first or n4th </f:if>
哪些情况更适合某些情况(特别是在使用时) 内联语法中的条件,您无法在其中扩展为标记模式 为了获得对f:else的访问,使用新的if参数)。
TYPO3 6.2 LTS和7 LTS
对于更复杂的if-Conditions(如几个或/和组合),您可以在your_extension/Classes/ViewHelpers/
中添加自己的ViewHelper。您只需要扩展流体AbstractConditionViewHelper
。与Fluid交互的简单if-ViewHelper看起来像这样:
class IfViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper {
/**
* renders <f:then> child if $condition is true, otherwise renders <f:else> child.
*
* @param boolean $condition View helper condition
* @return string the rendered string
* @api
*/
public function render($condition) {
if ($condition) {
return $this->renderThenChild();
} else {
return $this->renderElseChild();
}
}
}
您在自己的ViewHelper中所要做的就是添加比$condition
更多的参数,例如$or
,$and
,$not
等。然后您只需编写if -phditions在php中呈现then或者其他孩子。对于您的示例,您可以使用以下内容:
class ExtendedIfViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper {
/**
* renders <f:then> child if $condition or $or is true, otherwise renders <f:else> child.
*
* @param boolean $condition View helper condition
* @param boolean $or View helper condition
* @return string the rendered string
*/
public function render($condition, $or) {
if ($condition || $or) {
return $this->renderThenChild();
} else {
return $this->renderElseChild();
}
}
}
文件将在your_extension / Classes / ViewHelpers / ExtendedIfViewHelper.php中然后你必须在Fluid-Template中添加你的命名空间(这样就可以在模板中启用your_extension / Classes / ViewHelpers /中所有自编的ViewHelpers :
{namespace vh=Vendor\YourExtension\ViewHelpers}
并在您的模板中调用它:
<vh:extendedIf condition="{logoIterator.isFirst}" or="{logoIterator.cycle} % 4">
<f:then>Do something</f:then>
<f:else>Do something else</f:else>
</vh:extendedIf>
编辑:已更新。
答案 1 :(得分:11)
使用当前情况更新此信息:
在TYPO3v8及更高版本上,支持以下语法,完全符合您的用例:
<f:if condition="{logoIterator.isFirst}">
<f:then>First</f:then>
<f:else if="{logoIterator.cycle % 4}">n4th</f:else>
<f:else if="{logoIterator.cycle % 8}">n8th</f:else>
<f:else>Not first, not n4th, not n8th - fallback/normal</f:else>
</f:if>
此外还支持这样的语法:
<f:if condition="{logoIterator.isFirst} || {logoIterator.cycle} % 4">
Is first or n4th
</f:if>
哪些情况更适合某些情况(特别是在内联语法中使用条件时,您无法扩展到代码模式,以便使用新f:else
访问if
参数)。
答案 2 :(得分:6)
v:if.condition将在vhs V2.0中弃用 使用v:if stack: https://github.com/FluidTYPO3/vhs/issues/493
答案 3 :(得分:4)
您还可以使用If Condition Extend ViewHelper提供的VHS extension:
<v:if.condition>
<v:if.condition.extend>
{logoIterator.isFirst} || {logoIterator.cycle % 4} == 0
</v:if.condition.extend>
<f:then>Output if TRUE</f:then>
<f:else>Output if FALSE</f:else>
</v:if.condition>
旁注:VHS扩展提供了许多有用的ViewHelpers。我觉得很多都应该包含在TYPO3液体中。
答案 4 :(得分:4)
对于许多情况,它足以使用数组比较 - 因此您不必创建自定义视图助手。
和
<f:if condition="{0:user.number,1:user.zip}=={0:123,1:01234}">
OR
<f:if condition="{0:user.number,1:user.zip}!={0:false,1:false}">
可悲的是,这只是为了检查是否设置了一个变量而不是一个值。但是对于很多情况来说这已经足够了。
PS :(通过此数组比较,您还可以比较字符串)
答案 5 :(得分:1)
除了Daniels的回答之外,我制作了一个ViewHelper,它接受多个条件,带有“和” - 模式(默认)或“或” - 模式:
<?php
namespace TLID\Contentelements\ViewHelpers;
class IfViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
/**
* Checks conditions
*
* @param mixed $checks
* @param string $type
*
* @return boolean whether is array or not
*/
public function render($checks, $type = "and") {
$success = $type === "and" ? true : false;
$doc = new \DOMDocument();
$doc->loadHTML($this->renderChildren());
$xpath = new \DOMXpath($doc);
// get store values
$storeNodes = $xpath->query("//body/store");
$store = "";
foreach ($storeNodes as $storeNode) {
foreach ($storeNode->childNodes as $childNode) {
$store .= $doc->saveHTML($childNode);
}
}
// do the actual check
foreach ($checks as $check) {
if (
($type === "and" && (is_array($check) && count($check) === 0 || is_object($check) && get_object_vars($check) === 0 || empty($check))) ||
(is_array($check) && count($check) !== 0 || is_object($check) && get_object_vars($check) !== 0 || !empty($check))
) {
$success = $type === 'and' ? false : true;
break;
}
}
// render content
$renderQueryElement = $success ? "success" : "failure";
$renderNodes = $xpath->query("//body/" . $renderQueryElement);
$content = "";
foreach ($renderNodes as $renderNode) {
foreach ($renderNode->childNodes as $childNode) {
$content .= $doc->saveHTML($childNode);
}
}
//insert contents
$matches;
$content = preg_replace("/<use[^>]*><\/use>/", $store, $content);
//return rendered content
return $content;
}
}
?>
虽然它可以写得更好,但它确实有效。 以下是我如何使用它:
{namespace vhs=TLID\contentelements\ViewHelpers}
<vhs:if checks="{0: settings.link}">
<f:comment><!-- store the content --></f:comment>
<store>
<f:if condition="{images}">
<f:for each="{images}" as="image">
<f:image image="{image}" alt="{image.description}" title="{image.title}" />
</f:for>
</f:if>
<vhs:if checks="{0: settings.headline, 1: settings.text}" type="or">
<success>
<div>
<f:if condition="{settings.headline}"><h2><f:format.nl2br><vhs:shy>{settings.headline}</vhs:shy></f:format.nl2br></h2></f:if>
<f:if condition="{settings.text}"><p><f:format.nl2br><vhs:shy>{settings.text}</vhs:shy></f:format.nl2br></p></f:if>
</div>
</success>
</vhs:if>
</store>
<f:comment><!-- use the content of this container on success --></f:comment>
<success>
<vhs:link href="{settings.link}" target="{settings.target}" class="box">
<use />
</vhs:link>
</success>
<f:comment><!-- use the content of this container on failure --></f:comment>
<failure>
<div class="box">
<use />
</div>
</failure>
</vhs:if>
它还有一个store-element,因为我不喜欢它两次写相同的代码。因此,您可以选择保存一些流体并将其传递给成功和失败容器,而无需重复。
答案 6 :(得分:0)
是的,这感觉不对,但这是你能做到的唯一方法。这是viewhelper :: https://fluidtypo3.org/viewhelpers/fluid/master/IfViewHelper.html
的一个非常好的网站答案 7 :(得分:0)
对我来说,最好的方式是使用&#39; f:循环&#39;。如果我需要将每个第3个元素划分为行,我只会这样做:
<v:variable.set name="wraper" value='</div><div class="row">' />
<f:for each="{items}" as="item" iteration="itemIterator">
....
<f:cycle values="{0: '', 1: '', 2: '{wraper}'}" as="cycle">
{cycle -> f:format.raw()}
</f:cycle>
...
</f:for>
答案 8 :(得分:0)
如果你有CObjects帮助这个逻辑OR的解决方法:
public void onResponse(String response) {
Log.d("2pg",response);
Toast.makeText(getApplicationContext(),response,Toast.LENGTH_LONG).show();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
//recyclerView.setAdapter(new CardAdapter(listWorkers, this));
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
//Finally initializing our adapter
adapter = new CardAdapter(listWorkers, getApplicationContext());
recyclerView.setAdapter(adapter);
getData();
}
public void getData(){
Worker worker=new Worker();
worker.setImageUrl("http://vorkal.com/images/vorkal_cover.PNG");
worker.setName("name");
worker.setLocation("location");
worker.setRating(5);
worker.setId(1);
worker.setPhone(784512369);
worker.setOccupation("occupation");
worker.setPrice(20);
worker.setReview("Review");
listWorkers.add(worker);
adapter.notifydatasetchanged()
}
流体如果条件:
# Sidebar | 1 ColPos = 78
lib.sidebar1 < styles.content.get
lib.sidebar1.select.where = colPos=78
# Sidebar | 2 ColPos = 79
lib.sidebar2 < styles.content.get
lib.sidebar2.select.where = colPos=79
#LogicalOR
lib.tempLogicalOrSidebar = COA
lib.tempLogicalOrSidebar {
10 < lib.sidebar1
10.stdWrap.override.cObject =< lib.sidebar2
}
答案 9 :(得分:0)
如果条件与 f:if,v:variable.set 和 v:math 相结合,则可以实现复杂的条件。使用数学ViewHelper来完成魔术并将其结果存储在变量中。然后使用比较器验证并对其进行操作。
以下是我的示例代码:
<f:for each="{customers}" as="customer" iteration="iterator">
<v:variable.set name="isFirst" value="{v:math.modulo(a: iterator.cycle, b: settings.itemsperrow, fail: 0)}" />
<f:if condition="{isFirst}==1">
<div class="row">
</f:if>
<div class="col-md-{settings.colWidth}">
<div class="clientlogo_ref">
<f:image src="{customer.logo.originalResource.publicUrl}" />
</div>
</div>
<f:if condition="{isFirst}==0">
</div>
</f:if>
</f:for>
此代码开始/结束每个X项的网格行,由 settings.itemsperrow 定义。这是可变的,可以在插件的配置中设置。它使用modulo来计算 iterator.cycle(以1开头的计数器)mod settings.itemsperrow 。如果结果为1,则它是行的第一个元素。 0表示它是最后一个,因此必须关闭行。
答案 10 :(得分:0)
2017年状态:
以下是使用stack属性的现代VHS viewhelper条件的示例。此示例还包含NULL检查和逻辑或(<v:if stack="{0: '{itemId}', 1:'==', 2:NULL, 3: '||', 4: '{itemId}', 5: '==', 6: '{falMedia.uid}'}">
<f:then>
...
</f:then>
</v:if>
)以显示它是如何完成的。
NULL
请注意function makeExec(command) {
return function(/* ignore results */) {
return new Promise(function(resolve, reject) {
child_process.exec(command, function(err, stdout, stderr) {
if (err != null) reject(Object.assign(err, {stderr}));
else resolve(stdout);
});
});
});
}
Promise.resolve()
.then(makeExec("git pull"))
.then(makeExec("git push -u origin branchname"))
.then(makeExec("git pull origin develop"))
.then(makeExec("git checkout develop"))
.then(makeExec("git merge branchname"))
.then(makeExec("git push"))
.catch(function(err) {
//display an error message
})
未引用!